'CGFloat' 不能转换为 'UInt8' 和 Swift 和 Xcode 6 beta 4 的其他 CGFloat 问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24873219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
‘CGFloat’ is not convertible to ‘UInt8' and other CGFloat issues with Swift and Xcode 6 beta 4
提问by kasplat
In case this illuminates the problem, here's the original Objective-C code.
如果这能说明问题,这里是原始的 Objective-C 代码。
int x = (arc4random()%(int)(self.gameView.bounds.size.width*5)) - (int)self.gameView.bounds.size.width*2;
int y = self.gameView.bounds.size.height;
drop.center = CGPointMake(x, -y);
I started out with this code. Lines 2 and 3 are fine, I'm presenting them for clarity later.
我从这段代码开始。第 2 行和第 3 行很好,我将在稍后呈现它们以供清晰。
let x = CGFloat(arc4random_uniform(UInt32(self.gameView.bounds.size.width * 5))) - self.gameView.bounds.size.width * 2
let y = self.gameView.bounds.size.height
dropView.center = CGPointMake(x, -y)
In Xcode 6 beta 3, it was necessary to cast the arc4random_uniform UInt32 result to CGFloat in order for the minus and multiplication to work. This doesn't work anymore and the compiler shows an error:
在 Xcode 6 beta 3 中,有必要将 arc4random_uniform UInt32 结果转换为 CGFloat 以便减法和乘法工作。这不再起作用,编译器显示错误:
‘CGFloat' is not convertible to ‘UInt8'
“CGFloat”不可转换为“UInt8”
The release notes state:
发行说明指出:
"CGFloat is now a distinct floating-point type that wraps either a Float on 32-bit architectures or a Double on 64-bit architectures. It provide all of the same comparison and arithmetic operations of Float and Double and may be created using numeric literals. Using CGFloat insulates your code from situations where your code would be !fine for 32-bit but fail when building for 64-bit or vice versa. (17224725)"
“CGFloat 现在是一种独特的浮点类型,它包装了 32 位架构上的 Float 或 64 位架构上的 Double。它提供了 Float 和 Double 的所有相同的比较和算术运算,并且可以使用数字文字创建. 使用 CGFloat 可以将您的代码与以下情况隔离开来:您的代码适用于 32 位,但在为 64 位构建时失败,反之亦然。(17224725)"
Am I just doing something wrong with types? I don't even know how to describe this problem better to submit a bug report to Apple for beta 4. Pretty much every single Swift project I have that does any kind of point or rect manipulation got hit by this issue, so I'm looking for some sanity.
我只是在类型上做错了吗?我什至不知道如何更好地描述这个问题来向 Apple 提交 Beta 4 的错误报告。几乎我拥有的每个 Swift 项目都被这个问题击中了任何类型的点或矩形操作,所以我寻找一些理智。
采纳答案by Arkku
Since Swift doesn't have implicit type conversions, you must specify all the type conversions that take place. What makes this case particularly tedious, is that currently Swift seems to lack direct conversions between CGFloat
and types such as UInt32
, and you must go through an intermediate type as you've discovered.
由于 Swift 没有隐式类型转换,您必须指定发生的所有类型转换。使这个案例特别乏味的是,目前 Swift 似乎缺乏CGFloat
和 类型之间的直接转换UInt32
,并且您必须通过您发现的中间类型。
In the end, two double conversions are needed for the arc4random_uniform
:
最后,需要两次双转换arc4random_uniform
:
let bounds = CGRectMake(0.0, 0.0, 500.0, 500.0)
var x = CGFloat(UInt(arc4random_uniform(UInt32(UInt(bounds.size.width) * 5))))
x -= bounds.size.width * 2
let center = CGPointMake(x, -bounds.size.height)
回答by HazA
Had the same problem ... try wrapping
有同样的问题......尝试包装
arc4random_uniform
with
和
Int()
like
喜欢
Int(arc4random_uniform)
this worked for me ... don't know why Swift/Xcode hast problems converting unsigned INT's
这对我有用......不知道为什么 Swift/Xcode 在转换未签名的 INT 时遇到问题
回答by Chris Conover
TL;DR simple shortcuts cause HCF: Halt and Catch Fire bugs
TL;DR 简单快捷方式导致 HCF:Halt and Catch Fire 错误
Note that there are some obvious work legal work arounds like implementing conversion to and from CGFloat:
请注意,有一些明显的工作法律变通办法,例如实现与 CGFloat 的转换:
Totally legal, but don't do this:
完全合法,但不要这样做:
extension Float {
func __conversion() -> CGFloat { return CGFloat(self) }
}
extension CGFloat {
func __conversion() -> Float { return Float(self) }
func __conversion() -> Double { return Double(self) }
}
extension Double {
func __conversion() -> CGFloat { return CGFloat(self) }
}
I did not notice when typing, but later my machine kept overheating and hanging and SourceKit went to 300-500%, and the swift proceess + kernel_task took up 10+ gigs of RAM, consuming all that was left of my 16 gigs. It took a long time to trace it back to this - it wasn't swift.
打字时我没有注意到,但后来我的机器一直过热并挂起,SourceKit 达到 300-500%,并且 swift 进程 + kernel_task 占用了 10 多场 RAM,消耗了我 16 场比赛中剩下的所有内容。追溯这件事花了很长时间——这并不迅速。
回答by kasplat
@Arkku provided the correct solution, so the one-liner for x is...
@Arkku 提供了正确的解决方案,因此 x 的单行是...
let x = CGFloat(UInt(arc4random_uniform(UInt32(UInt(self.gameView.bounds.size.width) * 5)))) - self.gameView.bounds.size.width * 2
As of Xcode 6 beta 5, you can still use an intermediate conversion if you want and your code will continue to work. However, it is no longer necessary, so the following now works as expected.
从 Xcode 6 beta 5 开始,您仍然可以根据需要使用中间转换,并且您的代码将继续工作。但是,它不再是必需的,因此现在可以按预期工作。
let x = CGFloat(arc4random_uniform(UInt32(self.gameView.bounds.size.width * 5))) - self.gameView.bounds.size.width * 2
Since the original question is only relevant to Xcode 6 beta 4, what is the proper way to handle the question? Is there a historical mark? Should it be deleted?
由于原始问题仅与 Xcode 6 beta 4 相关,那么处理该问题的正确方法是什么?有历史印记吗?应该删除吗?