Casting von CGFloat, um in Swift zu schweben

91

Ich muss einen Wert als speichern Float, aber die Quelldaten sind CGFloat:

let myFloat : Float = myRect.origin.x

Dies führt jedoch zu einem Compilerfehler: 'NSNumber' ist nicht vom Subtyp 'Float'.

Also, wenn ich es explizit so besetze:

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

Dies führt jedoch wiederum zu dem Compilerfehler: 'Der Ausdruckstyp' Float 'kann nicht in' Float 'konvertiert werden.'

Was ist der richtige Weg, um dies zu tun und den Compiler zufrieden zu stellen?

Andrew Ebling
quelle
8
Beachten Sie, dass auf 64-Bit-Systemen das Umwandeln von CGFloat in Float an Genauigkeit verliert. CGFloat ist 64-Bit auf 64-Bit-Systemen und 32-Bit auf 32-Bit-Systemen, Float ist immer 32-Bit. Um dies zu vermeiden, können Sie Double anstelle von Float verwenden.
Lukas
Wenn Sie einen CGFloat in Xcode aufrufen und sehen, wo er definiert ist, werden Sie feststellen, dass er als Float auf 32-Bit-Architektur und als Double auf 64-Bit-Architektur typisiert ist.
JCPennypincher

Antworten:

173

Sie können den Float()Initialisierer verwenden:

let cgFloat: CGFloat = 3.14159
let someFloat = Float(cgFloat)
Erik
quelle
17
Die Verwendung von "float" als Variablenname ist etwas verwirrend. Vielleicht ändert sich etwas in "swFloat"?
Fermats kleiner Student
2
"'float' ist etwas verwirrend". Ernsthaft?
AlvinfromDiaspar
2
@AlvinfromDiaspar Ja, wahrscheinlich, da andere Sprachen floatanstelle von verwenden Float, sieht es also so aus, als ob dieser Typ / dieses Schlüsselwort anstelle eines Variablennamens verwendet wird.
Supuhstar
29

Wenn Sie so faul sind wie ich, definieren Sie in einer Extensions.swift Folgendes:

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

Dann können Sie tun:

var someCGFloatFromFloat = 1.3.f
var someCGFloatFromInt = 2.f
var someFloatFromCGFloat = someCGFloatFromFloat.swf
Hyouuu
quelle
1
sieht aus wie ein Kandidat für generische Struktur
μολὼν.λαβέ
@ Ian Ich verstehe deine Frage nicht ... ein Beispiel?
Hyouuu
13

Normalerweise ist es die beste Lösung, den Typ und die Verwendung CGFloatauch in Swift beizubehalten. Das liegt daran, dass CGFloat32-Bit- und 64-Bit-Computer unterschiedliche Größen haben.

Das Schlüsselwort askann nur für dynamisches Casting (für Unterklassen) verwendet werden, z

class A {
}

class B : A {
}

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

Allerdings Double, Int, Floatusw. sind nicht Unterklassen voneinander, also zu „cast“ müssen Sie eine neue Instanz erstellen, zB

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
Sulthan
quelle
Beachten Sie, dass Sie aseinen generischen Typ auch in einen konkreten Typ umwandeln können. Zum Beispiel, wenn Sie eine Funktion haben , die eine generische Art akzeptiert , dass Konform BinaryInteger, können Sie es werfen können Intmit as?oder as!.
Peter Schorn