Подтвердить что ты не робот

Класс Pure Swift, соответствующий протоколу со статическим методом - проблема с повышением уровня

Учитывая, что у нас есть протокол Swift с одним методом static:

protocol Creatable: class {
    static func create() -> AnyObject
}

и чистый класс Swift, который соответствует протоколу:

class Foo : Creatable {
    static func create() -> AnyObject {
        return Foo() as AnyObject
    }
}

Позже, когда вы пытаетесь использовать этот протокол, работая по типу Creatable например:

var f : Creatable = Foo.self
f.create()

Компилятор жалуется на следующее:

error: type 'Foo.Type' does not conform to protocol 'Creatable'

Вопрос в следующем: это ограничение Swift, или я использую протоколы и метод static/class неправильно.

Objective-C эквивалент будет выглядеть примерно так:

Class someClass = [Foo class];
if ([someClass conformsToProtocol:@protocol(Creatable)]) {
    [(Class <Foo>)someClass create];
}
4b9b3361

Ответ 1

A Creatable указывает на экземпляр Foo, а не на сам тип Foo.

Чтобы получить эквивалент реализации протокола уровня класса, вам понадобится экземпляр Creatable.Type:

let c: Creatable.Type = Foo.self

Однако при попытке использовать его вы получите сообщение об ошибке:

// error: accessing members of protocol type value 'Creatable.Type' is unimplemented
c.create()

Все, что сказал, есть причина, почему вы не можете просто использовать функции для выполнения своего требования вместо метатипов?

let f = Foo.create
// f is now a function, ()->AnyObject, that creates Foos
let someFoo = f()

Ответ 2

Использование .Type - это ключ:

var f : Creatable.Type = Foo.self

И это больше не дает ошибку "unimplemented". См. Полный код ниже:

protocol Creatable: class {
    static func create() -> AnyObject
}

class Foo : Creatable {
    static func create() -> AnyObject {
        return Foo() as AnyObject
    }
}

var f : Creatable.Type = Foo.self
f.create()