编辑:我已经重申并希望通过here来澄清这个问题。现在,我已经添加了解决方案。
我已经为foo()
采用我的struct
的默认功能定义了一个函数(请参见附件中的protocol
)。它应用针对其他两个变量定义的+
运算符,它们本身采用其他protocols
,并且+
在那些协议之一中定义。使用associatedtype
键入变量。
我收到消息:
二进制运算符'+'不能应用于类型为'Self.PointType'和'Self.VectorType'的操作数
如果我在struct
中实现该函数(请参见附件中的bar()),该函数将起作用,因此,我确定+运算符确实起作用。
我的示例被缩减为在操场上工作所需的最低限度。只需删除LineProtocol extension
中的注释即可获得错误。在我看来Self.PointType
是Point
,而Self.VectorType
是Vector
。
要清楚:我使用associatedtype
的原因是因为示例中许多不同的struct
都采用了这三种协议,所以我不能直接命名它们
public protocol PointProtocol {
associatedtype VectorType: VectorProtocol
var elements: [Float] { get set }
}
extension PointProtocol {
public static func +(lhs: Self,rhs:VectorType) -> Self {
var translate = lhs
for i in 0..<2 { translate.elements[i] += rhs.elements[i] }
return translate
}
}
public protocol VectorProtocol {
associatedtype VectorType: VectorProtocol
var elements: [Float] { get set }
}
public struct Point: PointProtocol {
public typealias PointType = Point
public typealias VectorType = Vector
public var elements = [Float](repeating: 0.0,count: 2)
public init(_ x: Float,_ y: Float) {
self.elements = [x,y]
}
}
public struct Vector: VectorProtocol {
public typealias VectorType = Vector
public static let dimension: Int = 2
public var elements = [Float](repeating:Float(0.0),y]
}
}
public protocol LineProtocol {
associatedtype PointType: PointProtocol
associatedtype VectorType: VectorProtocol
var anchor: PointType { get set }
var direction: VectorType { get set }
}
extension LineProtocol {
// public func foo() -> PointType {
// return (anchor + direction)
// }
}
public struct Line: LineProtocol {
public typealias PointType = Point
public typealias VectorType = Vector
public var anchor: PointType
public var direction: VectorType
public init(anchor: Point,direction: Vector) {
self.anchor = anchor
self.direction = direction
}
public func bar() -> Point {
return (anchor + direction)
}
}
let line = Line(anchor: Point(3,4),direction: Vector(5,1))
print(line.bar())
//print(line.foo())
解决方案改编自@Honey的建议: 将扩展名替换为:
extension LineProtocol where Self.VectorType == Self.PointType.VectorType {
public func foo() -> PointType {
// Constraint passes VectorType thru to the PointProtocol
return (anchor + direction)
}
}