2014-06-10 17 views
77

ho bisogno di memorizzare un valore come Float, ma i dati di origine è un CGFloat:Casting CGFloat galleggiare Swift

let myFloat : Float = myRect.origin.x 

ma questo genera l'errore del compilatore: 'NSNumber' non è del sottotipo ' float '

Quindi, se io scaccio esplicitamente in questo modo:

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

ma questo a sua volta provoca l'errore del compilatore:' Impossibile convertire il tipo di espressione 'Fl oat 'a' Float ''

Qual è il modo corretto per farlo e soddisfare il compilatore, per favore?

+7

essere consapevoli del fatto che a 64 bit sistemi, la fusione di CGFloat su Float perde precisione - CGFloat è 64 bit su sistemi a 64 bit e 32 bit su sistemi a 32 bit, Float è sempre a 32 bit. Per evitare questo, potresti usare Double invece di Float. – Lukas

+0

possibile duplicato di [swift: Confusione dovuta a nessuna conversione implicita di CGFloat] (http://stackoverflow.com/questions/24118134/swift-confusion-due-to-no-implicit-conversion-of-cgfloat) – Sulthan

+0

se si scavare su un CGFloat in Xcode e vedere dove è definito vedrai che è tipizzato come float su architettura a 32 bit e doppio su architettura a 64 bit. – jcpennypincher

risposta

142

È possibile utilizzare il Float() inizializzatore:

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

utilizzando "float" come nome di variabile è un po 'di confusione, forse il cambiamento è qualcosa come "swFloat"? – Will

+0

"'float' è un po 'confuso". Sul serio? – AlvinfromDiaspar

+0

@AlvinfromDiaspar Sì, probabilmente poiché altri linguaggi utilizzano 'float' invece di' Float', quindi sembra tipo/parola chiave anziché il nome di una variabile. – Supuhstar

13

Di solito, la soluzione migliore è quello di mantenere il tipo e l'uso CGFloat, anche in Swift. Questo perché CGFloat ha dimensioni diverse su macchine a 32 bit e 64 bit.

La parola chiave as può essere utilizzata solo per la trasmissione dinamica (per sottoclassi), ad es.

class A { 
} 

class B : A { 
} 

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

Tuttavia, Double, Int, Float ecc non sono sottoclassi di ogni altro, quindi, a "cast" è necessario creare una nuova istanza, per esempio

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

Più ragionevole :) – Tirth

24

Se siete come pigri come me, in un Extensions.swift definire quanto segue:

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

allora si può fare:

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

sembra un candidato per la struttura generica –

+0

@Ian Non capisco la tua domanda ... un esempio? – hyouuu