2016-11-30 2 views
2

У меня возникли проблемы с попыткой ограничить общие требования типа только к ссылочным типам. Вот пример кода:Тип ссылочного типа быстрого типа

class WeakHolder<Element: AnyObject> { 
    weak var element: Element? 

    init(element: Element) { 
     self.element = element 
    } 
} 

protocol Animal: class { } 

class Dog: Animal { } 

let dog: Animal = Dog() 
let holder = WeakHolder<Animal>(element: dog) // Error: Using "Animal" as a concrete type conforming to protocol 'AnyObject' is not supported. 

Если изменить общие требования к <Element: class>, я получаю ошибку class constraint can only appear on protocol declarations.

Это ограничение дженериков? Пометить протокол как класс достаточно, чтобы иметь слабую ссылку на этот протокол, нет ли эквивалента в дженериках?

+0

Собака не является объектом AnyObject, поскольку собака является протоколом –

+0

Основываясь на моем небольшом опыте, это может быть ограничение для дженериков с быстрым 2.3. Возможно, вы сможете исправить это, используя классы вместо протоколов. –

+0

Мне нужно использовать протоколы в моей реализации. – Mark

ответ

0

Простой ответ заключается в том, что у вас не может быть общего типа, который является протоколом.

Выписывая синтаксис дает понять, как это работает: class/struct GenericType<TypeName: TypeConstraints> {}

let thing = GenericType<Type>() where Type is a class or struct that adheres to any constraints

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

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

Вы можете взглянуть на The Generics Manifesto, если хотите посмотреть направление движения. Снимая его, я не нашел ничего, непосредственно связанного с вашим вариантом использования, но он довольно специфичен, поэтому он не может быть включен в параметры документа.

+0

Ах, ограничение обобщенного класса именно то, что я ищу. Приятно знать, что это рассматривается для будущей версии Swift. – Mark

0

Другим решением, которое работало в моем конкретном случае заключается в следующем:

class WeakHolder<Element: AnyObject> { 
    weak var element: Element? 

    init(element: Element) { 
     self.element = element 
    } 
} 

protocol Animal: class { } 

class Dog: Animal { } 

let dog: Animal = Dog() 
let holder = WeakHolder<AnyObject>(element: dog as AnyObject) 

При обращении к элементу, мне просто нужно выполнить опущенными назад к моему протоколу. Конечно, я потеряю время компиляции при использовании этого класса со значениями типов, но это не проблема в моей ситуации.

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