我想在Swift中使用一阶公民类型来决定调用哪个函数。
func sf(v: [Float]) -> Float{
}
func df(v: [Double]) -> Double {
}
func f<T: RealType>(seq ls: [T]) -> T {
if T.self == Float.self {
return sf(ls) // 1. where sf: Float -> Void
} else if T.self == Double.self {
return df(ls) // 2. where df : Double -> Void
}
}
类型推理系统无法注意到在一个分支T == Float和Double在另一个分支下?
这是一个缺少的功能,复杂的功能还是错误?
修改:
typealias RealType = protocol<FloatingPointType, Hashable, Equatable, Comparable, FloatLiteralConvertible, SignedNumberType>
我的原型但将成为协议
答案 0 :(得分:1)
您正在尝试将泛型给出的静态分辨率与运行时决策结合起来,但这是不可能的。
您可以简单地为f
和Float
重载Double
以获得所需内容:
func f(seq ls: [Float]) -> Float {
return sf(ls) // 1. where sf: Float -> Void
}
func f(seq ls: [Double]) -> Double {
return df(ls) // 2. where df : Double -> Void
}
但是,如果您希望RealType
成为通用占位符,可以使用Float
或Double
以外的其他类型,那么您可以执行以下操作:
protocol RealType {
static func processArray(v: [Self]) -> Self
}
extension Float: RealType {
static func processArray(v: [Float]) -> Float {
return sf(v)
}
}
extension Double: RealType {
static func processArray(v: [Double]) -> Double {
return df(v)
}
}
func sf(v: [Float]) -> Float{
return 0
}
func df(v: [Double]) -> Double {
return 0
}
func f<T: RealType>(seq ls: [T]) -> T {
return T.processArray(ls)
}
这将为您提供类型安全性,这是Swift的主要优势之一,以及可扩展性,因为无论何时需要在f
上添加对其他类型的支持,您只需将该类型声明为符合{{ 1}},并实现RealType
方法。