我正在编写结构来表示向量和矩阵,有些运算符可以使用它们。但是这些运算符的一些示例用法会产生类型错误,我无法解释。
这是我的图书馆减少的排泄量(A
是一种矩阵类型,B
是一种矢量类型,对于那些感兴趣的人:
struct A { }
struct B { }
func *(left: A, right: A) -> A { return A() }
func *(left: A, right: B) -> B { return B() }
let a: A = A()
let b: B = (a * a) * B()
在Swift Playground中运行它会产生以下编译器错误:
error: Test.playground:2:20: error: 'A' is not convertible to 'B'
let b: B = (a * a) * B()
~~~~~~~~^~~~~
内联一些变量,在某些情况下将a * a
作为单独的变量提取和/或从变量中删除类型注释,或者解决错误或产生不同的错误。
我不是在寻找一种解决方法,我正在努力了解这里发生了什么,我是在做错事还是在编译器中发现了一个错误。
我正在运行Xcode 9.2。
答案 0 :(得分:4)
对我来说这看起来像个错误。如果我们省略类型注释(哪个 不管怎么说都不需要):
let a = A()
let b = (a * a) * B()
然后编译器抱怨"模糊使用":
main.swift:14:12: error: ambiguous reference to member '*'
let b = (a * a) * B()
^
main.swift:7:6: note: found this candidate
func *(left: A, right: A) -> A { return A() }
^
main.swift:8:6: note: found this candidate
func *(left: A, right: B) -> B { return B() }
^
Swift.Float:4:24: note: found this candidate
public static func *(lhs: Float, rhs: Float) -> Float
^
Swift.Double:4:24: note: found this candidate
public static func *(lhs: Double, rhs: Double) -> Double
Swift.Float80:4:24: note: found this candidate
public static func *(lhs: Float80, rhs: Float80) -> Float80
^
Swift.UInt8:234:24: note: found this candidate
public static func *(lhs: UInt8, rhs: UInt8) -> UInt8
^
Swift.Int8:234:24: note: found this candidate
public static func *(lhs: Int8, rhs: Int8) -> Int8
// ... and many more ...
没有意义,因为那些重载不适用
两个A
个操作数。
似乎编译器被混淆了#34;因为有这么多
*
运算符的重载定义。问题不是
与自定义运算符一起发生,编译没有问题:
infix operator <*>: MultiplicationPrecedence
struct A { }
struct B { }
func <*>(left: A, right: A) -> A { return A() }
func <*>(left: A, right: B) -> B { return B() }
let a = A()
let b = (a <*> a) <*> B()
我建议在https://bugs.swift.org提交错误,并使用中间版 变量:
let a = A()
let a2 = a * a
let b = a2 * B()
或中间演员:
let a = A()
let b = ((a * a) as A) * B()
作为解决方法。