Кастинг CGFloat плавати в Свіфт


91

Мені потрібно зберегти значення як a Float, але вихідними даними є CGFloat:

let myFloat : Float = myRect.origin.x

але це призводить до помилки компілятора: 'NSNumber' не є підтипом 'Float'

Отже, якщо я явно кину його так:

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

але це, в свою чергу, призводить до помилки компілятора: 'Не вдається перетворити тип виразу' Float 'у' Float ''

Який правильний спосіб це зробити і задовольнити компілятор, будь ласка?


8
Майте на увазі, що в 64-розрядних системах передача CGFloat у Float втрачає точність - CGFloat становить 64 біти в 64-бітних системах і 32 біти в 32-бітових системах, Float завжди становить 32 біти. Щоб цього уникнути, ви можете використовувати Double замість Float.
Лукас


якщо ви детально розглянете CGFloat у Xcode і побачите, де він визначений, ви побачите, що він typedef'd як плаваючий на 32-бітній архітектурі та подвійний на 64-бітній архітектурі.
jcpennypincher

Відповіді:


173

Ви можете використовувати Float()ініціалізатор:

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

17
використання "float" як назви змінної дещо заплутане, можливо, зміна полягає у чомусь на зразок "swFloat"?
Маленький студент Ферма

2
"" float "дещо бентежить". Серйозно?
AlvinfromDiaspar

2
@AlvinfromDiaspar Так, ймовірно, оскільки інші мови використовують floatзамість Float, тому виглядає, що цей тип / ключове слово замість імені змінної.
Супухстар

29

Якщо ви такі ледачі, як я, у Extensions.swift визначте наступне:

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

Тоді ви можете зробити:

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

1
виглядає як кандидат на загальну структуру
μολὼν.λαβέ

@Ian Я не розумію твого питання ... приклад?
hyouuu,

13

Зазвичай найкращим рішенням є збереження типу та використання CGFloat, навіть у Swift. Це тому, що CGFloatмає різний розмір на 32-бітних та 64-бітних машинах.

Ключове слово asможна використовувати лише для динамічного лиття (для підкласів), наприклад

class A {
}

class B : A {
}

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

Однак Double, Int, і Floatт.д., не підкласи один від одного, тому «кидком» ви повинні створити новий екземпляр, наприклад ,

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

Зверніть увагу, що ви також можете використовувати asдля переливання загального типу в конкретний тип. Наприклад, якщо у вас була функція, яка приймає загальний тип, який відповідає BinaryInteger, ви можете передати її за Intдопомогою as?або as!.
Пітер Шорн,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.