Взгляните очень внимательно на следующее:
// Note that this protocol can only be applied to reference types.
protocol Ref: class {
var zibbles: Int { get set }
}
class Reference: Ref {
var zibbles: Int = 42
}
// Note very carefully that we are NOT passing an
// instance, but a type itself.
func thwip<T: AnyObject>(into target: T.Type) {
}
// This compiles.
thwip(into: Reference.self)
// This fails to compile.
thwip(into: Ref.self)
Каким бы редким ни был случай, это то, что язык должен уметь делать для полноты.Компилятор знает, что любой экземпляр Ref
должен соответствовать AnyObject
, поэтому ограничение типа на thwip
должно работать, но это не так.
Обратите внимание, что если мы удалим ограничение AnyObject
изthwip
, затем он компилируется, но это побеждает цель.Я хочу знать, имеет ли переданный протокол ссылочную семантику или нет.
// thwip without AnyObject
func thwip<T>(into target: T.Type) {
}
// Compiles, but useless to me
thwip(into: Ref.self)
Обратите внимание, что следующее изменение также не поможет нам:
// Here we've changed class to AnyObject
protocol Ref: AnyObject {
var zibbles: Int { get set }
}
Это потому, что Ref: class
и Ref: AnyObject
являются синонимами.Вы можете подтвердить это, сложив их вместе:
protocol Ref: class, AnyObject {}
Компилятор предупредит вас о избыточном соответствии, хотя он все равно будет компилироваться.
Обратите внимание, что есть очень похожее, но лучшеИзвестная ошибка компилятора:
protocol Base {}
protocol Ref: Base {}
func thwip<T: Base>(into target: T.Type) {
}
// Does not compile
thwip(into: Ref.self)
Тем не менее, компилятор выдает совершенно другие ошибки для этого случая, по сравнению с той, с которой у меня проблема.В моем случае я получаю «Невозможно вызвать 'thwip' со списком аргументов типа '(type: Ref.Protocol)'".В последнем случае я получаю «В типе аргумента« Ref.Protocol »,« Ref »не соответствует ожидаемому типу« Base »».