【发布时间】:2023-03-19 20:56:01
【问题描述】:
我正在尝试在 Swift 中实现一个通用的符号函数,以便它可以与任何浮点类型一起使用:
func sign<T> (value:T) -> T {
if value < 0.0 {
return -1.0
}
if value > 0.0 {
return 1.0
}
return 0.0
}
但是这个错误阻碍了:
二元运算符“
【问题讨论】:
我正在尝试在 Swift 中实现一个通用的符号函数,以便它可以与任何浮点类型一起使用:
func sign<T> (value:T) -> T {
if value < 0.0 {
return -1.0
}
if value > 0.0 {
return 1.0
}
return 0.0
}
但是这个错误阻碍了:
二元运算符“
【问题讨论】:
如果您将T 限制为SignedNumberType,您将能够做任何您想做的事情。它继承自 Comparable 并且可以从整数文字转换,这是您需要的两件事。
func sign<T: SignedNumberType> (value:T) -> T {
if value < 0 {
return -1
}
if value > 0 {
return 1
}
return 0
}
【讨论】:
SignedNumberType 不包括 Double 参数的初始化器,因此单独使用此方法; value < 0.0 比较很难通用。
您可以创建一个类型约束(下面的MyFloats),您的浮点类型符合。你让这个类型约束本身符合Comparable,这样你就可以在比较泛型的值时使用小于二元中缀运算符<。此外,对于上面给出的示例,MyFloats 类型约束只需要包含一个蓝图; Double 参数的初始化程序。对于Double、Float 和CGFloat 类型,此初始化程序已经存在,但由于协议无法知道哪些类型符合它,因此您需要包含此蓝图。
protocol MyFloats : Comparable {
init(_ value: Double)
}
extension Double : MyFloats { }
extension Float : MyFloats { }
extension CGFloat : MyFloats { }
func sign<T: MyFloats> (value:T) -> T {
if value < T(0.0) {
return T(-1.0)
}
if value > T(0.0) {
return T(1.0)
}
return T(0.0)
}
【讨论】:
sign 函数仅包含实际上可以表示为整数文字的“双文字”(1.0 为 1,0.0 为 0 等),我相信 Nate Cooks 下面的解决方案会对您来说更可取,因为您无需创建自定义协议并将类型扩展到此。但是请注意,SignedNumberType 解决方案将允许所有符合此协议的类型(不仅仅是浮点类型)调用您的函数sign。
Double、Float 和 CGFloat),您可以在下面的解决方案中修改类型约束增加对协议FloatingPointType:func sign<T: protocol<SignedNumberType, FloatingPointType>> ( ...的一致性
看this的回答。对于您的用例,您需要创建一个新的 protocol 扩展 Comparable 并使用 extension 扩展 Float 和 Double Swift 类型。
你终于可以使用这个协议作为泛型参数的条件了。
func sign<T : MyCustomNumberProtocol> (value:T) -> T
【讨论】:
NumericType(在链接线程中)不明确符合Comparable,因此不能仅从MyCustomNumberProtocol 推断出< 运算符的存在.