Casting CGFloat to Float en Swift


91

Necesito almacenar un valor como Float, pero los datos de origen son CGFloat:

let myFloat : Float = myRect.origin.x

pero esto da como resultado el error del compilador: 'NSNumber' no es del subtipo 'Float'

Entonces, si lo lanzo explícitamente así:

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

pero esto a su vez da como resultado el error del compilador: 'No se puede convertir el tipo de expresión' Float 'a' Float ''

¿Cuál es la forma correcta de hacer esto y satisfacer al compilador, por favor?


8
Tenga en cuenta que en sistemas de 64 bits, la conversión de CGFloat a Float pierde precisión: CGFloat es de 64 bits en sistemas de 64 bits y de 32 bits en sistemas de 32 bits, Float siempre es de 32 bits. Para evitar esto, puede usar Double en lugar de Float.
Lukas


Si profundiza en un CGFloat en Xcode y ve dónde está definido, verá que está definido como un flotante en una arquitectura de 32 bits y un doble en una arquitectura de 64 bits.
jcpennypincher

Respuestas:


173

Puedes usar el Float()inicializador:

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

17
usar "float" como nombre de variable es algo confuso, ¿quizás el cambio sea algo como "swFloat"?
Pequeña estudiante de Fermat

2
"'flotar' es algo confuso". ¿Seriamente?
AlvinfromDiaspar

2
@AlvinfromDiaspar Sí, probablemente ya que otros idiomas usan en floatlugar de Float, por lo que parece ese tipo / palabra clave en lugar de un nombre de variable.
Supuhstar

29

Si eres tan vago como yo, en un Extensions.swift defina lo siguiente:

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) }
}

Entonces puedes hacer:

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

1
parece un candidato para estructura genérica
μολὼν.λαβέ

@Ian, no entiendo tu pregunta ... ¿un ejemplo?
hyouuu

13

Por lo general, la mejor solución es mantener el tipo y el uso CGFloat, incluso en Swift. Eso es porque CGFloattiene un tamaño diferente en máquinas de 32 bits y 64 bits.

La palabra clave solo asse puede utilizar para la conversión dinámica (para subclases), por ejemplo

class A {
}

class B : A {
}

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

Sin embargo, Double, Int, Floatetc no son subclases de uno al otro, por lo tanto, a "fundido" tiene que crear una nueva instancia, por ejemplo,

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

Tenga en cuenta que también puede utilizar aspara convertir un tipo genérico en un tipo concreto. Por ejemplo, si tenía una función que acepta un tipo genérico que se ajusta a BinaryInteger, puede convertirlo en Intusando as?o as!.
Peter Schorn
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.