2015-04-24 4 views
4

У меня есть 2 протокола. Мне нужен первый (NameProtocol) для принудительного применения Equatable протокола. В то время как у другого класса (BuilderProtocol) есть метод, который возвращает первый (NameProtocol).Быстродействующий протокол, форсирующий равный протокол

public protocol NameProtocol : Equatable { 
    var name: String { get } 
} 

public protocol BuilderProtocol { 
    func build() -> NameProtocol? // Compiler error 
    init() 
} 

Ошибка компилятора: «Протокол„NameProtocol“может быть использован только в качестве общего ограничения, поскольку он имеет Самость или связанные с ними требования типа»

мне нужно вернуть объект по сборке(), чтобы возвращать объект, соответствующий NameProtocol и на котором я могу определить ==

Есть ли способ, которым я могу сделать эту работу?

Благодаря


При использовании typealias в BuilderProtocol, как я могу сделать заявление работы массива?

public protocol OtherRelatedProtocol { 
    var allNames : Array<NameProtocol> { get } 
} 

Заключение

я удалить Equatable и реализовать метод IsEqual.

public protocol NameProtocol { 
    func isEqual(nameable: NameProtocol) -> Bool 
    var name: String { get } 
} 
+0

Это сообщение об ошибке вводит в заблуждение (все еще в 3.0.2); он должен читать «* if * it has». – Raphael

ответ

3

Если вы знакомы с Java или C#, протоколы Swift находятся на полпути между генериками и интерфейсами. Одна вещь, которую вы можете сделать в протоколе, например, это:

protocol Foo { 
    func compareWith(foo: Self) 
} 

Классы, реализующие этот протокол будет иметь метод compareWith, которые принимают объект своего собственного типа (а не объект типа Foo).

Это то, что компилятор называет «Self или связанные требования типа», и это то, как определено Equatable (ему нужен operator==, который принимает два операнда Self). Однако недостатком этих протоколов является то, что вы можете использовать их только в качестве общих ограничений: вы не можете использовать их в качестве типа выражения.

Решение заключается в использовании дженериков. В этом случае вы должны сделать свой общий протокол ProtocolBuilder с ограничением, которое тип реализует NameProtocol.

public protocol NameProtocol : Equatable { 
    var name: String { get } 
} 

public protocol BuilderProtocol { 
    typealias T: NameProtocol 
    func build() -> T? 
    init() 
} 
+0

Это не скомпилируется, потому что это не то, как вы делаете общий протокол. – matt

+0

Да, матовый, я должен был проверить его. – zneak

+0

Особенно, если вы просто скажете, что я уже сказал в своем комментарии. :) – matt

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