Truyền CGFloat sang Float trong Swift


91

Tôi cần lưu trữ một giá trị dưới dạng a Float, nhưng dữ liệu nguồn là CGFloat:

let myFloat : Float = myRect.origin.x

nhưng điều này dẫn đến lỗi trình biên dịch: 'NSNumber' không thuộc loại phụ 'Float'

Vì vậy, nếu tôi truyền nó một cách rõ ràng như thế này:

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

nhưng điều này lại dẫn đến lỗi trình biên dịch: 'Không thể chuyển đổi loại biểu thức' Float 'thành' Float ''

Cách chính xác để làm điều này và làm hài lòng trình biên dịch là gì?


8
Lưu ý rằng trên hệ thống 64 bit, việc truyền CGFloat sang Float sẽ làm mất độ chính xác - CGFloat là 64 bit trên hệ thống 64 bit và 32 bit trên hệ thống 32 bit, Float luôn là 32 bit. Để tránh điều này, bạn có thể sử dụng Double thay vì Float.
Lukas


nếu bạn đi sâu vào CGFloat trong Xcode và xem nơi nó được xác định, bạn sẽ thấy rằng nó được đánh máy như một float trên kiến ​​trúc 32 bit và một kép trên kiến ​​trúc 64 bit.
jcpennypincher

Câu trả lời:


173

Bạn có thể sử dụng trình Float()khởi tạo:

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

17
sử dụng "float" làm tên biến hơi khó hiểu, có lẽ thay đổi là một cái gì đó giống như "swFloat"?
Fermat's Little Student,

2
"float" hơi khó hiểu ". Nghiêm túc?
AlvinfromDiaspar

2
@AlvinfromDiaspar Có, có thể là vì các ngôn ngữ khác sử dụng floatthay thế Float, vì vậy nó trông giống như loại / từ khóa đó thay vì một tên biến.
Supuhstar

29

Nếu bạn cũng lười biếng như tôi, trong Extensions.swift, hãy xác định những điều sau:

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

Sau đó, bạn có thể làm:

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

1
trông giống như một ứng cử viên cho cấu trúc chung
μολὼν.λαβέ Ngày

@Tôi không hiểu câu hỏi của bạn ... một ví dụ?
hyouuu

13

Thông thường, giải pháp tốt nhất là giữ nguyên kiểu và cách sử dụng CGFloat, ngay cả trong Swift. Đó là vì CGFloatcó kích thước khác nhau trên máy 32bit và 64bit.

Từ khóa chỉ ascó thể được sử dụng để truyền động (cho các lớp con), ví dụ:

class A {
}

class B : A {
}

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

Tuy nhiên, Double, Int, Floatvv không phải là lớp con của nhau, do đó để "đúc" bạn phải tạo một đối tượng mới, ví dụ như

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

Lưu ý rằng bạn cũng có thể sử dụng asđể đúc một loại chung thành một loại bê tông. Ví dụ: nếu bạn có một hàm chấp nhận một kiểu chung phù hợp BinaryInteger, bạn có thể truyền nó sang Intsử dụng as?hoặc as!.
Peter Schorn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.