我遇到快速类型转换的问题,让我说我有这个变量
let anim = CABasicAnimation(keyPath: "position")
let sublayersCount : NSInteger = 4
let sublayerIdx :NSInteger = 2
let instanceDelay : CGFloat = 0.1;
我想对他们做一些数学计算。在目标c中,我这样写
anim.beginTime += (sublayersCount - sublayerIdx - 1) * instanceDelay;
但是在快速,同样感觉非常笨拙,有没有办法改善它?
anim.beginTime = CFTimeInterval(CGFloat(anim.beginTime) + CGFloat(sublayersCount - sublayerIdx - 1) * instanceDelay)
答案 0 :(得分:2)
我同意这很麻烦。你可以通过提供临时重载来解决它,就像
一样func * (lhs: Double, rhs: CGFloat) -> CGFloat {
return CGFloat(lhs * Double(rhs))
}
func + (lhs: Double, rhs: CGFloat) -> CGFloat {
return CGFloat(lhs) + CGFloat(rhs)
}
func - (lhs: Int, rhs: Int) -> Double {
return lhs - rhs
}
anim.beginTime = CFTimeInterval(anim.beginTime + (sublayersCount - sublayerIdx - 1) * instanceDelay)
当然,这个特定的例子非常具体,但你明白了。
话虽这么说,有一个库提供了更广泛的方便重载,允许您隐式转换不同的数字类型。看看:https://github.com/seivan/ScalarArithmetic/blob/master/ScalarArithmetic/ScalarArithmetic.swift
答案 1 :(得分:0)
Swift中的类型转换是一场噩梦,老实说是个笑话。我无法相信苹果认为这是任何人想要的好主意。幸运的是,Swift具有强大的运算符重载和类型扩展,因此我们可以解决这个问题。
这不是所有类型的完整示例,但我们的想法是我们有运算符重载来将类型转换为更大的尺寸和/或符号或浮点数。
例如,UInt8 + Float返回一个Float(操作中最大的签名类型)。 UInt + Int返回Int(相同的大小,但朝向标志)。 UInt8 + Uint返回UInt(较大的大小)。假设我们想要保留数字的符号并通过转换为更大的大小来防止溢出(因此UInt8(255)+ 1.5返回Float(256.5)而不是截断或崩溃)。
注意:我不建议将其放在现有的代码库中,因为它破坏了Swift中的许多隐含假设。
/*
Arithmetic on integers (signed or unsigned) & floats casts up to Float
Arithmetic on signed integers & unsigned integers (of any size) casts up to Int
Arithmetic on unsigned integers & unsigned integers (of any size) casts up to UInt
Float + Int = Float
Float + UInt = Float
UInt + Int = Int
UInt + UInt = UInt
UInt8 + UInt = UInt
UInt8 + Int = Int
*/
// MARK: Floating Point Arithmetic Operators
protocol FloatingPointArithmetic {
var toFloat: Float { get }
}
func + <T: FloatingPointArithmetic> (lhs: T, rhs: Float) -> Float { return lhs.toFloat + rhs }
func - <T: FloatingPointArithmetic> (lhs: T, rhs: Float) -> Float { return lhs.toFloat - rhs }
func * <T: FloatingPointArithmetic> (lhs: T, rhs: Float) -> Float { return lhs.toFloat * rhs }
func / <T: FloatingPointArithmetic> (lhs: T, rhs: Float) -> Float { return lhs.toFloat / rhs }
// MARK: Integer Arithmetic Operators
protocol IntegerArithmetic: FloatingPointArithmetic {
var toSigned: Int { get }
var toUnsigned: UInt { get }
}
protocol SignedIntegerArithmetic: IntegerArithmetic {}
protocol UnsignedIntegerArithmetic: IntegerArithmetic {}
func + <T: SignedIntegerArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> Int { return lhs.toSigned + rhs.toSigned }
func + <T: UnsignedIntegerArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> UInt { return lhs.toUnsigned + rhs.toUnsigned }
func + <T: UnsignedIntegerArithmetic, U: SignedIntegerArithmetic> (lhs: T, rhs: U) -> Int { return lhs.toSigned + rhs.toSigned }
func - <T: SignedIntegerArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> Int { return lhs.toSigned - rhs.toSigned }
func - <T: UnsignedIntegerArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> UInt { return lhs.toUnsigned - rhs.toUnsigned }
func - <T: UnsignedIntegerArithmetic, U: SignedIntegerArithmetic> (lhs: T, rhs: U) -> Int { return lhs.toSigned - rhs.toSigned }
func * <T: SignedIntegerArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> Int { return lhs.toSigned * rhs.toSigned }
func * <T: UnsignedIntegerArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> UInt { return lhs.toUnsigned * rhs.toUnsigned }
func * <T: UnsignedIntegerArithmetic, U: SignedIntegerArithmetic> (lhs: T, rhs: U) -> Int { return lhs.toSigned * rhs.toSigned }
func / <T: SignedIntegerArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> Int { return lhs.toSigned / rhs.toSigned }
func / <T: UnsignedIntegerArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> UInt { return lhs.toUnsigned / rhs.toUnsigned }
func / <T: UnsignedIntegerArithmetic, U: SignedIntegerArithmetic> (lhs: T, rhs: U) -> Int { return lhs.toSigned / rhs.toSigned }
func + <T: FloatingPointArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> Float { return lhs.toFloat + rhs.toFloat }
func + <T: FloatingPointArithmetic, U: SignedIntegerArithmetic> (lhs: T, rhs: U) -> Float { return lhs.toFloat + rhs.toFloat }
func - <T: FloatingPointArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> Float { return lhs.toFloat - rhs.toFloat }
func - <T: FloatingPointArithmetic, U: SignedIntegerArithmetic> (lhs: T, rhs: U) -> Float { return lhs.toFloat - rhs.toFloat }
func * <T: FloatingPointArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> Float { return lhs.toFloat * rhs.toFloat }
func * <T: FloatingPointArithmetic, U: SignedIntegerArithmetic> (lhs: T, rhs: U) -> Float { return lhs.toFloat * rhs.toFloat }
func / <T: FloatingPointArithmetic, U: UnsignedIntegerArithmetic> (lhs: T, rhs: U) -> Float { return lhs.toFloat / rhs.toFloat }
func / <T: FloatingPointArithmetic, U: SignedIntegerArithmetic> (lhs: T, rhs: U) -> Float { return lhs.toFloat / rhs.toFloat }
// MARK: Supported Types
extension Float: FloatingPointArithmetic {
var toFloat: Float { return self }
}
extension UInt: FloatingPointArithmetic, UnsignedIntegerArithmetic {
var toSigned: Int { return Int(self) }
var toUnsigned: UInt { return self }
var toFloat: Float { return Float(self) }
}
extension UInt8: FloatingPointArithmetic, UnsignedIntegerArithmetic {
var toSigned: Int { return Int(self) }
var toUnsigned: UInt { return UInt(self) }
var toFloat: Float { return Float(self) }
}
extension Int: FloatingPointArithmetic, SignedIntegerArithmetic {
var toSigned: Int { return self }
var toUnsigned: UInt { return UInt(self) }
var toFloat: Float { return Float(self) }
}