Knowing the types
andmeta-types
in swift is not as important as in Objc. Where in objective c, you can instantiate an object out of a class name or modify classes at runtime, it’s not possible in pure swift.
了解swift中的类型和元类型并不像Objc那么重要。 在oc中,您可以在类名中实例化对象或在运行时修改类,在纯swift中是不可能的。
The fact that swift is a language that supports generics, and has little to no reflection capabilities, knowing and dealing with types
and meta-types
is not a very common task.
事实上swift是一种支持泛型的语言,几乎没有反射功能,知道和处理类型和元类型并不是一个非常常见的任务。
However, there are times when you need to know what type your instances (or classes) are. In that area, swift provides two ways of getting the types; calling type(of: )
on an instance, or .self
on a Class/Structure.
但是,有时您需要知道实例(或类)的类型。 在那个领域,swift提供了两种获取类型的方法; 在实例上调用type(of: ),或在类/结构上调用.self。
Type.self
The meta type of a type can be found by calling .self on a type. The returned type can either be a Class meta-type, a Struct meta-type or a Protocol meta-type.
可以通过在类型上调用.self来找到类型的元类型。 返回的类型可以是Class元类型,Struct元类型或Protocol元类型。
image.png
image.png
Even if the above look similar, they act different. The type return from calling NSString.self looks similar to an Objective C class. ”
即使上面看起来相似,它们的行为也不同。 调用NSString.self的类型返回类似于Objective C类
The object returned from calling MyClass.self is the swift metaType of MyClass. This object exposes init function and all the method defined in this class as curried method (read Instance Methods are Curried Functions in Swift).
从调用* MyClass.self 返回的对象是MyClass的swift元类型。 此对象将 init *函数和此类中定义的所有方法公开为curried方法
If we pass MyClass.self to NSStringFromClass we get the mangled class name.
如果我们将MyClass.self传递给NSStringFromClass,我们会得到错位的类名。
String.self returns a similar to calling self on a swift class. A difference to note here, if we pass it to NSStringFromClass we get a compilation error. This should not be surprising as string is a struct and not a class.
String.self返回一个类似于在swift类上调用self的方法。 这里要注意的区别是,如果我们将它传递给NSStringFromClass,我们会得到一个编译错误。 这不应该是令人惊讶的,因为字符串是结构而不是类。
type(of: )
If .self is used on a Type to returns its metatype, type(of: ) is used on an instance to return its metatype. The type returned is the same returned when calling .self on the instance static type.
如果在类型上使用.self返回其元类型,则在实例上使用type(of: )来返回其类型。 返回的类型与在实例静态类型上调用.self时返回的相同。
Comparing the dynamic type to the static type for most of the struct and types; we can compare instances of String as follows:
将动态类型与大多数结构和类型的静态类型进行比较; 我们可以比较String的实例如下:
image.png
Comparing types directly is considered bad practice and is discouraged. The safe swift way to correctly check the type of an instance we must swift’s is statement. To compare the doubles from above we would use (please ignore swift warning us that the result is always true)
直接比较类型被认为是不好的做法,并且不鼓励。 正确检查实例类型的安全快捷方式是使用 swift 的
is
语句。
image.png
We can create a new instance from a type. For example to create an instance from MyClass we can use the following:
我们可以从一个类型创建一个新实例。 例如,要从MyClass创建实例,我们可以使用以下内容:
image.png
image.png
Holding a metatype references
When storing the result of type(of: "")
or String.self
to a variable, the inferred type is String.Type, String.Type can so be used to annotate meta type variables:
将
type(of:""
或String.self
的结果存储到变量时,推断的类型是String.Type,String.Type可用于注释元类型变量:
Variable annotated with String.Type or any Struct.Type can only store that struct meta-type. The compiler won’t allow us to store another metatype to the same variable:
使用String.Type或任何Struct.Type注释的变量只能存储该struct meta-type。 编译器不允许我们将另一个元类型存储到同一个变量中:
image.png
For classes, since they can be subclassed, the behaviour is different. A BaseClass.Type can also hold references of SubClass.Type.
对于类,因为它们可以被子类化,所以行为是不同的。 BaseClass.Type也可以包含SubClass.Type的引用。
Bellow we store NSDictionary.self and NSMutableDictionary.self to the same variable:
Bellow我们将NSDictionary.self和NSMutableDictionary.self存储到同一个变量中:
image.png
Note that the opposite won’t work, if we annotated the type with NSMutableDictionary.Type the compiler won’t allow us to store a reference of NSDictionary.self.
请注意,相反的方法不起作用,如果我们用NSMutableDictionary.Type注释类型,编译器将不允许我们存储NSDictionary.self的引用。
image.png
A Protocol.Type variable, unsurprisingly, can hold a reference to any type thats implementing that protocol:
不出所料,Protocol.Type变量可以包含对实现该协议的任何类型的引用:
image.png
To note here, only protocols that don’t have associated type or Self requirements can be used to annotate variables. Protocols that have Self or associated type requirements can only use as generic constraints.
此处需要注意的是,只有没有关联类型或自我要求的协议才能用于注释变量。 具有Self或关联类型要求的协议只能用作通用约束。
image.png
As a final note, variables annotated with Any.Type can well, hold any type, whether the type is a structure or a class.
最后要注意的是,使用Any.Type注释的变量可以很好地保存任何类型,无论类型是结构还是类。
image.png