metatype .Type和.selfSwift有什么区别?
做.self并.Type返回struct?
我明白.self可以用来检查dynamicType.你怎么用的.Type?
Dev*_*ist 38
这是一个简单的例子:
func printType<T>(of type: T.Type) {
// or you could do "\(T.self)" directly and
// replace `type` parameter with an underscore
print("\(type)")
}
printType(of: Int.self) // this should print Swift.Int
func printInstanceDescription<T>(of instance: T) {
print("\(instance)")
}
printInstanceDescription(of: 42) // this should print 42
Run Code Online (Sandbox Code Playgroud)
假设每个实体由两个部分代表:
类型: # entitiy name #
元类型: # entity name # .Type
元类型类型是指任何类型的类型,包括类类型,结构类型,枚举类型和协议类型.
您可以快速注意到这是递归的,并且可以按类型等(((T.Type).Type).Type)进行.
.Type 返回元类型的实例.
我们有两种方法可以获得元类型的实例:
调用.self一个具体的类型Int.self,它将创建一个
静态元类型实例Int.Type.
从任何实例获取动态元类型实例
type(of: someInstance).
危险区域:
struct S {}
protocol P {}
print("\(type(of: S.self))") // S.Type
print("\(type(of: S.Type.self))") // S.Type.Type
print("\(type(of: P.self))") // P.Protocol
print("\(type(of: P.Type.self))") // P.Type.Protocol
Run Code Online (Sandbox Code Playgroud)
.Protocol是另一种仅在协议背景下存在的元类型.也就是说,我们没有办法表达我们想要的东西P.Type.这可以防止所有通用算法使用协议元类型,并可能导致运行时崩溃.
对于更好奇的人:
该type(of:)函数实际上是由编译器处理的,因为.Protocol创建了不一致.
// This implementation is never used, since calls to `Swift.type(of:)` are
// resolved as a special case by the type checker.
public func type<T, Metatype>(of value: T) -> Metatype { ... }
Run Code Online (Sandbox Code Playgroud)
Hon*_*ney 27
在哪里使用?
如果您正在编写/创建一个接受类型的函数,例如UIView.Type,不是实例,UIView()那么您将编写T.Type为参数的类型.预计什么作为参数可以是:String.self,CustomTableView.self,someOtherClass.self.
通常,需要类型的函数是为您实例化对象的函数.我可以想到两个很好的例子:
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "CustomTableViewCell")
Run Code Online (Sandbox Code Playgroud)
请注意,你通过了CustomTableViewCell.self.如果稍后您尝试将类型的tableView出列CustomTableViewCell但未注册CustomTableViewCell类型,那么它将崩溃,因为tableView尚未出列/实例化任何CustomTableViewCell类型的tableviewcells .
struct GroceryProduct: Codable {
var name: String
var points: Int
var description: String?
}
let json = """
{
"name": "Durian",
"points": 600,
"description": "A fruit with a distinctive scent."
}
""".data(using: .utf8)!
let decoder = JSONDecoder()
let product = try decoder.decode(GroceryProduct.self, from: json)
print(product.name)
Run Code Online (Sandbox Code Playgroud)
注意事项try decoder.decode(GroceryProduct.self, from: json).因为你传递GroceryProduct.self它知道它需要实例化一个类型的对象GroceryProduct.如果它不能那么它会抛出错误
更多关于内部及其工作原理:
类,结构或枚举类型的元类型是该类型的名称,后跟.Type.协议类型的元类型 - 不是在运行时符合协议的具体类型 - 是该协议的名称,后跟.Protocol.例如,的元类型 的类类型
SomeClass是SomeClass.Type与所述的元类型 的协议SomeProtocol是SomeProtocol.Protocol.来自Apple:metaType Type
引擎盖下 AnyClass是
typealias AnyClass = AnyObject.Type // which is why you see T.Type
Run Code Online (Sandbox Code Playgroud)
基本上,你在哪里都看到AnyClass,Any.Type,AnyObject.Type,其因为它需要的类型.我们看到的一个非常常见的地方是我们想要使用func 为tableView 注册一个类register.
func register(_ cellClass: Swift.AnyClass?, forCellReuseIdentifier identifier: String)
Run Code Online (Sandbox Code Playgroud)
如果你对"斯威夫特"的含义感到困惑.在上面做,然后看到这里的评论
以上内容也可以写成:
func register(_ cellClass: AnyObject.Type, forCellReuseIdentifier identifier: String)
Run Code Online (Sandbox Code Playgroud)
您可以使用后缀自表达式将类型作为值进行访问.例如,SomeClass.self返回SomeClass本身,而不是 SomeClass的实例.SomeProtocol.self返回SomeProtocol本身,而不是 在运行时符合SomeProtocol的类型的实例.您可以将类型(of :)表达式与类型实例一起使用,以将该实例的动态,运行时类型作为值进行访问,如以下示例所示:
来自Apple:metaType Type
游乐场代码:
简单的例子
struct Something {
var x = 5
}
let a = Something()
type(of:a) == Something.self // true
Run Code Online (Sandbox Code Playgroud)
很难的例子
class BaseClass {
class func printClassName() {
print("BaseClass")
}
}
class SubClass: BaseClass {
override class func printClassName() {
print("SubClass")
}
}
let someInstance: BaseClass = SubClass()
/* | |
compileTime Runtime
| |
To extract, use: .self type(of)
Check the runtime type of someInstance use `type(of:)`: */
print(type(of: someInstance) == SubClass.self) // True
print(type(of: someInstance) == BaseClass.self) // False
/* Check the compile time type of someInstance use `is`: */
print(someInstance is SubClass) // True
print(someInstance is BaseClass) // True
Run Code Online (Sandbox Code Playgroud)
我强烈建议您阅读有关类型的Apple文档.另见这里
new*_*cct 15
它们在语法上出现在不同的地方.
在语法上你必须指定类型的地方,Something.Type是一个有效的类型,对应于元类型(类的元类)的类型Something.Something.self不是类型的有效语法.
在语法上你必须编写表达式的地方,Something.self是一个有效的表达式.它是类型的表达式,Something.Type值是表示类型的事物(在类的情况下为"类对象")Something.Something.Type不是有效的表达式语法.
| 归档时间: |
|
| 查看次数: |
11901 次 |
| 最近记录: |