如何在 Swift 中进行类型转换?
How to Typecast in Swift?
我正在为 UIBezierPath 开发自定义路径,我得到了 "Cannot assign a value of type (CGFloat) to a value of type CGFloat." 我认为这是因为类型转换存在一些问题?我怎样才能解决这个问题? "X = (b2 - b1) / (m1 - m2)" 行和 "Y = m1 * X + b1" 行会弹出警告。
func lineIntersection(m1: CGFloat, b1: CGFloat, m2: CGFloat, b2: CGFloat, inout X: CGFloat, inout Y: CGFloat) -> Bool {
if m1 == m2 {
return false
} else if X = (b2 - b1)/(m1 - m2) {
return true
} else if Y = m1 * X + b1 {
return true
} else {
return false
}
}
稍后我会在另一个函数中调用这个函数
func xxx() {
var outX = CGFloat()
var outY = CGFloat()
lineIntersection(oldSlope, b1: oldIntercept, m2: newSlope, b2: newIntercept, X: &outX, Y: &outY)
}
Swift 没有零作为 "false" 值,您需要明确地与 if
中的 != 0
进行比较。此外,将分配移至单独的行,而不是将其作为条件的一部分。
除少数特殊情况外,浮点相等比较不可靠,这不太可能是其中之一。
我会删除 inout
参数和 return 一个可选的 CGPoint
,即 -> CGPoint?
。 Return nil
代表 false
,CGPoint
代表 true
。
结果函数(我完全删除了相等性检查;浮点除以零并不危险,我们可以稍后检查 Inf/NaN):
func lineIntersection(m1 m1: CGFloat, b1: CGFloat, m2: CGFloat, b2: CGFloat) -> CGPoint? {
let x = (b2 - b1) / (m1 - m2)
let y = m1 * x + b1
return y.isFinite ? CGPoint(x: x, y: y) : nil
}
在调用位置使用类似于:
if let intersection = lineIntersection(m1: m1, b1: b1, m2: m2, b2: b2) {
// use intersection.x and intersection.y
}
至于如何进行类型转换的字面问题(尽管这不是这里的问题),您甚至可以使用 CGFloat(value)
之类的东西初始化 "basic types",这会导致类型 [=42] =]转换 "creating" 来自value
的新CGFloat
。几种类型也有其他方法来指定转换的确切发生方式,例如,Int32(truncatingBitPattern: largerInteger)
照原样采用最低 32 位,而如果 Int32(largerInteger)
溢出或下溢,则会崩溃。这样的转换是通过 as
(已知在编译时成功)、as?
(在运行时尝试转换,nil
失败)、as!
(在运行时尝试转换)完成的,断言成功)。
我正在为 UIBezierPath 开发自定义路径,我得到了 "Cannot assign a value of type (CGFloat) to a value of type CGFloat." 我认为这是因为类型转换存在一些问题?我怎样才能解决这个问题? "X = (b2 - b1) / (m1 - m2)" 行和 "Y = m1 * X + b1" 行会弹出警告。
func lineIntersection(m1: CGFloat, b1: CGFloat, m2: CGFloat, b2: CGFloat, inout X: CGFloat, inout Y: CGFloat) -> Bool {
if m1 == m2 {
return false
} else if X = (b2 - b1)/(m1 - m2) {
return true
} else if Y = m1 * X + b1 {
return true
} else {
return false
}
}
稍后我会在另一个函数中调用这个函数
func xxx() {
var outX = CGFloat()
var outY = CGFloat()
lineIntersection(oldSlope, b1: oldIntercept, m2: newSlope, b2: newIntercept, X: &outX, Y: &outY)
}
Swift 没有零作为 "false" 值,您需要明确地与
if
中的!= 0
进行比较。此外,将分配移至单独的行,而不是将其作为条件的一部分。除少数特殊情况外,浮点相等比较不可靠,这不太可能是其中之一。
我会删除
inout
参数和 return 一个可选的CGPoint
,即-> CGPoint?
。 Returnnil
代表false
,CGPoint
代表true
。
结果函数(我完全删除了相等性检查;浮点除以零并不危险,我们可以稍后检查 Inf/NaN):
func lineIntersection(m1 m1: CGFloat, b1: CGFloat, m2: CGFloat, b2: CGFloat) -> CGPoint? {
let x = (b2 - b1) / (m1 - m2)
let y = m1 * x + b1
return y.isFinite ? CGPoint(x: x, y: y) : nil
}
在调用位置使用类似于:
if let intersection = lineIntersection(m1: m1, b1: b1, m2: m2, b2: b2) {
// use intersection.x and intersection.y
}
至于如何进行类型转换的字面问题(尽管这不是这里的问题),您甚至可以使用 CGFloat(value)
之类的东西初始化 "basic types",这会导致类型 [=42] =]转换 "creating" 来自value
的新CGFloat
。几种类型也有其他方法来指定转换的确切发生方式,例如,Int32(truncatingBitPattern: largerInteger)
照原样采用最低 32 位,而如果 Int32(largerInteger)
溢出或下溢,则会崩溃。这样的转换是通过 as
(已知在编译时成功)、as?
(在运行时尝试转换,nil
失败)、as!
(在运行时尝试转换)完成的,断言成功)。