Swift3 中不明确的运算符分辨率回归?
Ambiguous operator resolution regression in Swift3?
我有值类型来表示持续时间和频率(反转的持续时间)。想和他们一起做数学运算,我有以下运算符重载:
func * (a:Frequency, b:Duration) -> Double {
return a.numerator * (b / a.denominator)
}
因为我经常将这些与图形代码一起使用,所以我发现自己经常需要 CGFloat
响应而不是 Double
。所以我加了以下糖:
func * (a:Frequency, b:Duration) -> CGFloat {
return CGFloat(a * b)
}
这在 Swift2.2 中运行良好。编译器似乎根据预期的 return 类型找到并应用了合适的类型。但是对于 Swift3,情况似乎不再如此了?我收到 Ambiguous use of operator '*'
错误。它甚至告诉我它找到了两个候选函数,原始函数和出错的函数。
Swift3 中即将发生的变化是否符合预期?这是我以前逃脱但不应该逃脱的事情吗?还是倒退?
更新
你甚至不需要你自己的特殊 类 来做到这一点。在 XCode7 游乐场中,以下内容很好:
func * (a:String, b:Double) -> Double {
return Double(a)! * b
}
func * (a:String, b:Double) -> CGFloat {
return CGFloat(a * b)
}
let x:CGFloat = "4.2" * 3.0
let y:Double = "-1.1" * 22.2
但在 XCode8
中出现上述错误而失败
我认为这是旧版本编译器的错误。
无法确定是要使用 func * (a:String, b:Double) -> Double
函数还是对 func * (a:String, b:Double) -> CGFloat
的递归调用(是的,有一个 CGFloat 的构造函数将 CGFloat 作为参数)。
如果你像这样实现代码(明确你真正想要的功能),编译将能够推断出正确的功能:
func * (a:String, b:Double) -> CGFloat {
let result: Double = a * Double(b)
return CGFloat(result)
}
我有值类型来表示持续时间和频率(反转的持续时间)。想和他们一起做数学运算,我有以下运算符重载:
func * (a:Frequency, b:Duration) -> Double {
return a.numerator * (b / a.denominator)
}
因为我经常将这些与图形代码一起使用,所以我发现自己经常需要 CGFloat
响应而不是 Double
。所以我加了以下糖:
func * (a:Frequency, b:Duration) -> CGFloat {
return CGFloat(a * b)
}
这在 Swift2.2 中运行良好。编译器似乎根据预期的 return 类型找到并应用了合适的类型。但是对于 Swift3,情况似乎不再如此了?我收到 Ambiguous use of operator '*'
错误。它甚至告诉我它找到了两个候选函数,原始函数和出错的函数。
Swift3 中即将发生的变化是否符合预期?这是我以前逃脱但不应该逃脱的事情吗?还是倒退?
更新
你甚至不需要你自己的特殊 类 来做到这一点。在 XCode7 游乐场中,以下内容很好:
func * (a:String, b:Double) -> Double {
return Double(a)! * b
}
func * (a:String, b:Double) -> CGFloat {
return CGFloat(a * b)
}
let x:CGFloat = "4.2" * 3.0
let y:Double = "-1.1" * 22.2
但在 XCode8
中出现上述错误而失败我认为这是旧版本编译器的错误。
无法确定是要使用 func * (a:String, b:Double) -> Double
函数还是对 func * (a:String, b:Double) -> CGFloat
的递归调用(是的,有一个 CGFloat 的构造函数将 CGFloat 作为参数)。
如果你像这样实现代码(明确你真正想要的功能),编译将能够推断出正确的功能:
func * (a:String, b:Double) -> CGFloat {
let result: Double = a * Double(b)
return CGFloat(result)
}