我尝试打破,计算并稍后将对象连接到另一个类中。 所以我建立了协议:
typealias DataBreaker<T> = () -> [Double]
typealias DataJoiner<T> = (_ particles: [Double]) -> T
protocol SpaceIntepolatable {
associatedtype Atom
var breaker:DataBreaker<Atom> {get}
static var joiner:DataJoiner<Atom> {get}
}
并为Point构建扩展名:
extension Point:SpaceIntepolatable {
typealias Atom = Point
var breaker:DataBreaker<Atom> {
return {
return [self.x, self.y]
}
}
static var joiner:DataJoiner<Atom> {
return {particles in
return Atom(x: particles[0], y: particles[1])
}
}
}
直到现在没问题。我可以将Point
分成Array<Double>
let particles = atom.breaker()
但加入
let newAtom = Atom.joiner(particles)
导致编译器错误:
Cannot convert value of type 'Atom.Atom' to specified type 'Atom'
可能是因为joiner
是静态的。但是如何避免它并得到Atom
?
答案 0 :(得分:1)
当你不在课堂范围内时,你必须在Point
上调用它。
let newAtom = Point.joiner(particles)
修改强>
你说你有一个看起来像这样的泛型类:
class Space<Atom: SpaceIntepolatable> {
func test() {
let particles: [Double] = [0, 1]
let newAtom: Atom = Atom.joiner(particles)
}
}
现在,问题是newAtom
的类型不正确。 SpaceIntepolatable
协议未指定Point
和Point.Atom
属于同一类型。因此,Atom
(Point
)和Atom.Atom
(Point.Atom
)不被视为相同。我们想要的是Atom.Atom
。或者我们可以让类型被推断出来:
let newAtom: Atom.Atom = Atom.joiner(particles)
let newAtom = Atom.joiner(particles)
一般情况下,建议不要重复使用类型名称,因为这样会得到Atom.Atom
之类的内容。也许你真的想要这样的东西:
protocol SpaceIntepolatable {
var breaker: DataBreaker<Self> { get }
static var joiner: DataJoiner<Self> { get }
}
然后完全失去Atom
typealias,然后:
class Space<Atom: SpaceIntepolatable> {
func test() {
let particles: [Double] = [0, 1]
let newAtom: Atom = Atom.joiner(particles)
}
}
实际上会有效。