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

Метатип метатипа

В Swift мы можем написать следующую конструкцию:

class SomeClass {}
let metaMetatype: SomeClass.Type.Type = SomeClass.Type.self

Здесь metaMetatype не соответствует типу AnyObject (SomeClass.Type does). Строительство может быть даже дольше, если мы хотим:

let uberMetatype: SomeClass.Type.Type.Type.Type.Type.Type.Type.Type.Type.Type = SomeClass.Type.Type.Type.Type.Type.Type.Type.Type.Type.self

Являются ли эти конструкции имеющими смысл? Если SomeClass.Type.Type не объект, что это такое и почему мы можем его объявить?

4b9b3361

Ответ 1

Если SomeClass.Type.Type не объект, что это такое и почему мы можем его объявить?

Я попытаюсь проанализировать то, что вы просите.

SomeClass.Type.Type является метатипом метатипа. Метатипы существуют в Swift, потому что у Swift есть типы, которые не являются классами. Это наиболее похоже на концепцию Metaclass в Objective-C.

Lexicon.rst в Swift Open Source Repo имеет довольно хорошее объяснение:

метатип

Тип значения, представляющего тип. У Грега Паркера есть хорошая     объяснение Objective-C "метаклассы" , поскольку у Swift есть типы     которые не являются классами, используется более общий термин.

Мы также иногда ссылаемся на значение, представляющее тип как "метатип     объект" или просто "метатип", обычно в контекстах низкого уровня, таких как IRGen     и LLDB. Это технически некорректно (это просто "объект типа" ), но     малапропизм произошел в начале проекта и застрял.

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

Метаданные типа

Представление времени выполнения типа и все, что вы можете с ним сделать.     Как a Class в Objective-C, но для любого типа.

Обратите внимание, что вы не можете сделать что-то вроде NSObject().class в Swift, потому что Class является зарезервированным ключевым словом для создания класса. Так вы получите тип (или класс в этом случае) NSObject в Swift:

let nsObj = NSObject()
nsObj.classForCoder // NSObject.Type
nsObj.classForKeyedArchiver // NSObject.Type
nsObj.dynamicType // NSObject.Type

Обратите внимание, что nsObj и nsObj.self идентичны и представляют собой экземпляр этого NSObject.

Я не вижу, где в модуле Swift или с открытым исходным кодом, где типы допускают .Type, но я все еще ищу. Это может иметь отношение к наследованию от SwiftObject, объекта Objective-C, который все классы Swift наследуют (по крайней мере, на Mac).

Ответ 2

Тип класса также представлен в памяти (он имеет, например, собственные методы). Он представлен синглетоном, представляющим тип. (Это не экземпляр этого типа - что-то другое). Если вы назовете себя на тип, как этот SomeClass.self, вы возьмете экземпляр singleton, представляющий тип SomeClass.

Для получения дополнительной информации проверьте этот ответ