2014-06-10 28 views
77

muszę przechowywać wartość jako Float, ale dane źródło jest CGFloat:Casting CGFloat się unosić w Swift

let myFloat : Float = myRect.origin.x 

ale powoduje to błąd kompilatora: „NSNumber” nie jest podtypem " pływak „

Więc jeśli jawnie rzucić go tak:

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

ale to z kolei powoduje błąd kompilatora:” nie można przekonwertować typu ekspresji w „FL oat 'to' Float ''

Jaki jest prawidłowy sposób to zrobić i proszę o kompilator?

+7

Należy pamiętać, że w 64-bitowych systemy, rzutowanie CGFloat na Float traci precyzję - CGFloat ma 64 bity w systemach 64-bitowych i 32 bity w systemie 32-bitowym, Float ma zawsze 32 bity. Aby tego uniknąć, możesz użyć opcji Double zamiast Float. – Lukas

+0

możliwy duplikat [swift: Confusion z powodu niejawnej konwersji CGFloat] (http://stackoverflow.com/questions/24118134/swift-confusion-due-to-no-implicit-conversion-of-cgfloat) – Sulthan

+0

jeśli drążenie CGFloat w Xcode i zobaczenie, gdzie jest zdefiniowane, zobaczysz, że jest typowane jako float w 32-bitowej architekturze i podwójnej 64-bitowej architekturze. – jcpennypincher

Odpowiedz

142

Można użyć Float() inicjator:

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

użycie "float" jako nazwy zmiennej jest nieco mylące, może zmiana jest na coś takiego jak "swFloat"? – Will

+0

"Pływanie" jest nieco mylące ". Poważnie? – AlvinfromDiaspar

+0

@AlvinfromDiaspar Tak, prawdopodobnie, ponieważ inne języki używają 'float' zamiast' Float', więc wygląda jak ten typ/słowo kluczowe zamiast nazwy zmiennej. – Supuhstar

13

Zwykle najlepszym rozwiązaniem jest, aby rodzaj i używać CGFloat, nawet w Swift. To dlatego, że CGFloat ma inny rozmiar na komputerach 32-bitowych i 64-bitowych.

Słowo kluczowe as może być używane tylko do dynamicznego rzucania (dla podklas), np.

class A { 
} 

class B : A { 
} 

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

Jednak Double, Int, Float etc nie są podklasy siebie, więc do „cast” trzeba utworzyć nową instancję, na przykład

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 
+0

Bardziej rozsądne :) – Tirth

24

Jeśli tak leniwy jak ja, w Extensions.swift określić następujące:

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

Następnie można zrobić:

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

wygląda jak kandydat na ogólną strukturę –

+0

@Ian Nie rozumiem twojego pytania ... przykład? – hyouuu