2016-08-20 2 views
4

Я хочу, чтобы связанный тип был Self, но компилятор не имеет его.
Вот что я хочу, чтобы скомпилировать:Swift Self как связанный тип, связанный в протоколе

protocol Protocol { 
    // Error: Inheritance from non-protocol, non-class type 'Self' 
    associatedtype Type: Self 
} 

Вы можете спросить, почему бы просто не использовать Self вместо связанного типа? Просто потому, что я не могу: связанный тип наследуется от родительского протокола. И нет смысла изменять это в родительском протоколе.
Вот что-то похожее на то, что я пытаюсь сделать:

protocol Factory { 
    associatedtype Type 

    func new() -> Type 
} 

protocol SelfFactory: Factory { 
    associatedtype Type: Self // Same Error 
} 

Edit: ответ
Мэтта почти то, что я ищу. Он ведет себя так, как я хочу, во время выполнения, но во время компиляции это не является достаточно ограничительным.
Я хочу, чтобы это было невозможно:

protocol Factory { 
    associatedtype MyType 
    static func new() -> MyType 
} 

protocol SelfFactory: Factory { 
    static func new() -> Self 
} 

final class Class: SelfFactory { 

    // Implement SelfFactory: 
    static func new() -> Class { 
     return Class() 
    } 

    // But make the Factory implementation diverge: 
    typealias MyType = Int 

    static func new() -> Int { 
     return 0 
    } 
} 

Я хотел бы typealias в Class, чтобы вызвать ошибку переопределения или аналогичный.

+0

Сообщение об ошибке абсолютно верно. Источник проблемы указывается в ваших словах: «связанный тип наследуется от родительского протокола». Нет, это не так. Протоколы не выполняют «наследования». Вы не можете «переопределить» один протокол другим, как вы, кажется, пытаетесь сделать. Вы либо принимаете протокол, либо нет. – matt

+0

«Я бы хотел, чтобы типы данных в классе вызывали ошибку повторного выделения или подобное». Вы не можете предотвратить перегрузку! В Swift существуют сосуществования 'f() -> Int' и' f() -> String'. Вы задаете язык на другом языке. Вы не компилятор. - Другими словами, принятие протокола не мешает мне реализовывать другие методы, не требуемые протоколом! – matt

+0

Непонятно, что вы хотите и почему. Что вас удовлетворит? Возможно, ваш лучший выбор состоит в том, чтобы иметь два _ связанных протокола, Factory и SelfFactory. И я принимаю только одну из них. Неужели ты будешь счастлив? (Но, конечно, даже тогда вы не можете помешать мне принять их обоих, если мне это нравится.) – matt

ответ

3

Вы пытаетесь это сказать?

protocol Factory { 
    associatedtype MyType 
    func new() -> MyType 
} 

protocol SelfFactory: Factory { 
    func new() -> Self 
} 
+0

Это почти то, что мне нужно. Я отредактировал вопрос с более подробной информацией. Спасибо за ответ! – ThinkChaos

+0

Проведя еще некоторое время, сражаясь с этим, я считаю, что в настоящее время это лучшее решение. Я хотел бы сказать, что реализация 'SelfFactory'' Factory' является «окончательной», но я предполагаю, что этого не произойдет. И необходимость повторять каждое определение функции раздражает, но хорошо. – ThinkChaos

+0

На самом деле это работает, если я определяю 'SelfFactory' как пустой протокол и реализую метод' new' в расширении. – ThinkChaos

2

Я понимаю, что это старый вопрос, но вы можете сделать это из Swift 4.0:

protocol Factory { 
    associatedtype MyType 
    static func new() -> MyType 
} 

protocol SelfFactory: Factory where MyType == Self { } 

не там, где пункты большой?

Смежные вопросы