我制作了一个具有通用类型T的类,其中T应该仅是一个数值(CGFloat
,Double
,Int
等),并且应该能够转换为Double
。我尝试了几种类型,例如Numeric
和Equatable
,但这些类型的投放范围仍然太广。当转换为Double
时,类型应符合BinaryInteger
或BinaryFloatingPoint
,但我还没有找到一种使泛型符合两种类型之一的方法。
我想要的是:
class SomeClass<T:SomeNumberTypeThatAllowsConversionToDouble> {
var number: T
var doubleNumber: Double
init(number: T) {
self.number = number
self.doubleNumber = Double(number) //or some other function that converts from T to Double
}
}
[我不想要的是SomeClass
的两个独立扩展,其中一个人处理BinaryInteger
情况,一个人处理BinaryFloatingPoint
情况,因为那样会违背为什么我首先使用泛型的目的。
您想要实现的是约束T以符合一组固定的协议。
与我们在打字稿T:number|point|size
中拥有的非常相似>
下面是我在Swift中的解决方法。不是那么整洁。
protocol DoubleConvertible { }
extension Int:DoubleConvertible { }
extension CGFloat:DoubleConvertible { }
extension Double:DoubleConvertible {
static func convert(_ number:DoubleConvertible) -> Double {
if number is Int {
return Double(number as! Int)
} else if number is CGFloat {
return Double(number as! CGFloat)
} else {
return Double(number as! Double)
}
}
}
import UIKit
class SomeClass<T> where T:DoubleConvertible {
var number: T
var doubleNumber: Double
init(number: T) {
self.number = number
self.doubleNumber = Double.convert(number)
}
}
print(SomeClass<Int>(number: 10).doubleNumber)
print(SomeClass<Double>(number: 10.0).doubleNumber)
print(SomeClass<CGFloat>(number: CGFloat(integerLiteral: 10)).doubleNumber)
//10.0
//10.0
//10.0
print(SomeClass<CGPoint>(number: 10).doubleNumber)
//Type 'CGPoint' does not conform to protocol 'DoubleConvertible'