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?


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)

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

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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.