2014-12-12 4 views
2

У меня есть этот протокол:Обобщения по протоколу

protocol Addable 
{ 
    mutating func addNumber(value: Int) 
} 

и это расширение

extension Int : Addable 
{ 
    mutating func addNumber(value: Int) 
    { 
     self = self + value 
    } 
} 

Этот код:

var number : Int = 10 
    number.addNumber(10) 
    println(number) 

Правильно печатает 20

Теперь я хочу, чтобы расширить протокол Добавляется к другим типам. Если я правильно понимаю, что я не использую Generics с протоколом, но я использую ассоциированный тип:

protocol Addable 
{ 
    typealias AddableType 
    mutating func addNumber(value: AddableType) 
} 

Так что теперь, AddableType означает общий тип, и я могу продлить, например Float

extension Float : Addable 
{ 
    mutating func addNumber(value: Float) 
    { 
     self = self + value 
    } 
} 

    var another : Float = 10.5 
    another.addNumber(10.1) 
    println(another) 

печатается 20,6

Теперь я знаю, что я могу применять соответствующий тип в соответствии с протоколом

protocol Addable 
{ 
    typealias AddableType : AProtocol, AnotherProtocol // ... 
    mutating func addNumber(value: AddableType) 
} 

Но и здесь это вопрос, я не могу следить за соблюдением соответствия к типу или некоторых типов

protocol Addable 
{ 
    typealias AddableType : Int, Float 
    mutating func addNumber(value: AddableType) 
} 

Error: Inheritance from non-protocol, non-class type 'Int' 
Error: Inheritance from non-protocol, non-class type 'Float' 

Есть ли возможность сделать это?

ответ

3

Вы можете создать второй протокол и осуществить это на типах, которые вы хотите:

protocol AddableRequirement {} 

extension Int: AddableRequirement {} 
extension Float: AddableRequirement {} 

protocol Addable { 
    typealias AddableType: AddableRequirement 
    mutating func addNumber(value: AddableType) 
} 

Вы также можете использовать Self вместо typealias:

protocol Addable { 
    mutating func addNumber(value: Self) 
} 

Таким образом, ваши протокол требует, чтобы тип всегда добавлялся с собой.

+0

Хорошо, я пришел к тому же решению сразу же после написания вопроса :-) Принимается, потому что вы первый, кто ответил. И из-за подсказки «Я», которая очень полезна. Спасибо и всем остальным, которые ответили – LombaX

2

Вы можете определить новый протокол и объявить соответствие для типов, которые вы хотите разрешить.

protocol AllowedAddableType {} 

extension Int: AllowedAddableType {} 
extension Float: AllowedAddableType {} 
// ... 

protocol Addable 
{ 
    typealias AddableType: AllowedAddableType 
    mutating func addNumber(value: AddableType) 
} 
2

Типы могут соответствовать протоколам, а протоколы могут соответствовать протоколам, но протоколы не могут соответствовать типам. Наличие протокола, соответствующего типу, не имеет никакого смысла в грамматическом определении языка.

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

protocol TypeRestrictor {} 

extension Int: TypeRestrictor {} 
extension Float: TypeRestrictor {} 

protocol Addable { 
    typealias AddableType: TypeRestrictor 
    mutating func addNumber(value: AddableType) 
}