Как я могу ограничить параметры универсального c типа протоколами, которые ограничены AnyObject?
Примечание. Я не хочу ограничить свой параметр AnyObject, я бы хотел бы разрешить протоколы в качестве параметров для моего обобщенного типа c, но только протоколы, которые сами ограничены AnyObject.
Пример:
struct Gen<P>
where P: AnyObject // #1
{}
protocol CP: AnyObject {}
protocol SP {}
class C: CP {}
struct S: SP {}
let gc = Gen<CP>() // #2
let gs = Gen<SP>() // #3
Это дает ошибку как для №2, так и для # 3: 'Gen' requires that 'CP'/'SP' be a class type.
Если я удаляю строку # 1, то и # 2, и # 3 компилируются без ошибок.
Я хотел бы добиться, чтобы # 2 компилировался (потому что CP соответствует AnyObject), но # 3 не должен (потому что SP не соответствует AnyObject).
Есть ли способ сделать это?
В ответ на комментарий о том, почему я хочу это:
Я попытался реализовать WeakRef, чтобы у меня могли быть массивы (или другие коллекции), которые не сохраняют свои элементы , Я хотел, чтобы WeakRef разрешил протоколы в качестве своего параметра (а не только конкретные типы), чтобы я мог написать что-то вроде var observers: [MyObserverProtocol]
.
Единственный способ, который я нашел до сих пор (используя стирание типов), имеет недостаток, заключающийся в том, что теперь, если у меня есть протокол P и соответствующее значение типа T, то компилятор теперь позволяет мне объявлять переменную WeakRef<P>
и оберните в нее экземпляр T, но он не будет работать во время выполнения (работает только с типами ref). Я хотел бы получить ошибку компиляции в этом случае. Поэтому я бы хотел, чтобы WeakRef разрешал только протоколы с ограниченным классом в качестве своего параметра.
struct WeakRef<T> {
var value: T? { get { return (value_ as? T) }}
weak var value_: AnyObject?
init(value: T? = nil) { value_ = value as AnyObject }
}
Теперь WeakRef<ProtocolThatValueTypesCanConformTo>
или даже WeakRef<ValueType>
успешно компилируются, но, конечно, не будут работать во время выполнения, weakRef.value
всегда будет nil
.
Я хотел бы получить ошибку компиляции, если T является типом значения или это протокол, которому разрешено соответствовать типам значений. В этих случаях WeakRef на самом деле не имеет смысла, он имеет смысл только для типов ссылок и протоколов, которым могут соответствовать только типы ссылок.
Мне кажется, что это более общая проблема c, поэтому я не упомянул конкретный вариант использования c в исходном вопросе, но я могу ошибаться по этому поводу.