2016-12-05 2 views
1

У меня есть следующий код:Swift не может найти перегрузки, когда дженерики участвует

protocol MyEnum { 

} 

class MyClass { 
    func append(_ value: UInt8) { 
     print("uint8 \(value)") 
    } 

    func append(_ value: UInt16) { 
     print("uint16 \(value)") 
    } 

    func append<T: MyEnum>(_ value: T) { 
     print("myenum \(value)") 
    } 
} 

let c = MyClass() 

func appendAny<T>(_ value: T) { 
    switch value { 
    case let u8 as UInt8: 
     c.append(u8) 
    case let u16 as UInt16: 
     c.append(u16) 
    case let myenum as MyEnum: 
     c.append(myenum) 
    default: 
     assert(false) 
    } 
} 

Ошибка сообщается компилятором для линии c.append(myenum) с указанием

не может ссылаться на «Append» со списком аргументов (MyEnum)

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

+2

Это еще один вариант http://stackoverflow.com/questions/33112559/protocol-doesnt-conform-to-itself: Протокол не соответствует самому себе. Измените третий вариант на 'func append (_ value: MyEnum)', чтобы скомпилировать его. –

+0

Спасибо, что работал @MartinR. Наверное, я немного переоценил этот общий метод '' 'append'''. –

ответ

1

Как отметил Мартин в своем комментарии, вы должны изменить свой окончательный append() перегрузки быть:

func append(_ value: MyEnum) { 
    print("myenum \(value)") 
} 

Потому что вы хотите, чтобы рассматривать значение как «экземпляр протокола», а не «экземпляр конкретный тип, который соответствует протоколу ». Экземпляр, который имеет протокол типа, не является также конкретным типом, который соответствует этому протоколу.

Еще одно замечание: так как вы на самом деле не с помощью общих ограничений или каких-либо время компиляции свойства типа T (только во время выполнения литья), почему бы не просто изменить appendAny быть:

func appendAny(_ value: Any) { 
    switch value { 
    case let u8 as UInt8: 
     c.append(u8) 
    case let u16 as UInt16: 
     c.append(u16) 
    case let myenum as MyEnum: 
     c.append(myenum) 
    default: 
     assert(false) 
    } 
} 
Смежные вопросы