在Swift中将CGFloat转换为Float


91

我需要将值存储为Float,但是源数据是CGFloat

let myFloat : Float = myRect.origin.x

但这会导致编译器错误:“ NSNumber”不是子类型“ Float”

因此,如果我明确地将其像这样进行投射:

let myFloat : Float = myRect.origin.x as Float

但这反过来导致编译器错误:'无法将表达式的类型'Float'转换为'Float'

请问满足编译器要求的正确方法是什么?


8
请注意,在64位系统上,将CGFloat强制转换为Float会降低精度– CGFloat在64位系统上为64位,在32位系统上为32位,Float始终为32位。为避免这种情况,可以使用Double而不是Float。
卢卡斯2014年


如果您在Xcode中深入研究CGFloat并查看其定义位置,则将看到它被定义为32位体系结构上的浮点型和64位体系结构上的双精度型。
jcpennypincher 2014年

Answers:


173

您可以使用Float()初始化程序:

let cgFloat: CGFloat = 3.14159
let someFloat = Float(cgFloat)

17
使用“ float”作为变量名有些令人困惑,也许更改为诸如“ swFloat”之类的东西?
费马的小学生

2
“'float'有点令人困惑”。认真吗
AlvinfromDiaspar '16

2
@AlvinfromDiaspar是的,可能是因为其他语言使用float而不是Float,所以它看起来像是该类型/关键字而不是变量名。
Supuhstar

29

如果您像我一样懒惰,请在Extensions.swift中定义以下内容:

extension Int {
  var f: CGFloat { return CGFloat(self) }
}

extension Float {
  var f: CGFloat { return CGFloat(self) }
}

extension Double {
  var f: CGFloat { return CGFloat(self) }
}

extension CGFloat {
  var swf: Float { return Float(self) }
}

然后,您可以执行以下操作:

var someCGFloatFromFloat = 1.3.f
var someCGFloatFromInt = 2.f
var someFloatFromCGFloat = someCGFloatFromFloat.swf

1
看起来像普通的结构候选人
μολὼν.λαβέ

@Ian我不明白您的问题...一个例子吗?
hyouuu

13

通常,最好的解决方案是保留类型和use CGFloat,即使在Swift中也是如此。那是因为CGFloat在32位和64位计算机上大小不同。

关键字as只能用于动态转换(对于子类),例如

class A {
}

class B : A {
}

var a: A = B()
var b: B = a as B

然而DoubleIntFloat等不是子类对方,因此以“铸造”你必须创建一个新的实例,例如,

var d: Double = 2.0
var f: Float = Float(d) //this is an initialiser call, not a cast
var i: Int = Int(d) //this is an initialiser call, not a cast

请注意,您还可以as将通用类型转换为具体类型。例如,如果您的函数接受符合的通用类型,则BinaryInteger可以将其强制转换为Int使用as?as!
Peter Schorn于
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.