Static Var闭包返回Type.Type而不是Type

时间:2018-05-21 21:02:57

标签: swift

我尝试打破,计算并稍后将对象连接到另一个类中。 所以我建立了协议:

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

1 个答案:

答案 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协议未指定PointPoint.Atom属于同一类型。因此,AtomPoint)和Atom.AtomPoint.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)
    }
}

实际上会有效。