Закрытие Static Var возвращает Type.Type вместо Type - PullRequest
0 голосов
/ 22 мая 2018

Я пытаюсь разбить, посчитать, а затем объединить объекты внутри другого класса.Поэтому я создаю протокол:

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 голосов
/ 22 мая 2018

Вам нужно позвонить на 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)
    }
}

действительно будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...