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.