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
// 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 { ... }
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)
注意try decoder.decode(GroceryProduct.self, from: json)。因为你传递了GroceryProduct.self,它知道它需要示例化一个GroceryProduct类型的对象。如果它不能,那么它将抛出一个错误。关于JSONDecoder的更多信息,请参见well written answer 1.尝试查找某个类类型的值。示例尝试在navigationController的所有视图控制器中查找某个类型的视图控制器:
func popBackTo<T>(type: T.Type, in nav: UINavigationController? = nil, completion: ((T?) -> Void)? = nil) {
let nav = window?.rootViewController as? UINavigationController
guard let nav = nav, let destinationVC = nav.viewControllers.first(where: { $0 is T }) else {
return
}
nav.popToViewController(destinationVC, animated: true)
}
# Example call site:
popBackTo(LoginVC.self)
struct Something {
var x = 5
}
let a = Something()
type(of:a) == Something.self // true
铁证
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
5条答案
按热度按时间avwztpqn1#
下面是一个简单的例子:
假设每个实体由两个事物表示:
# entitiy name #
# entity name # .Type
元类型类型是指任何类型的类型,包括类类型、结构类型、枚举类型和协议类型。
Source.
你很快就会注意到这是递归的,可以使用
(((T.Type).Type).Type)
等类型。.Type
返回元类型的示例。有两种方法可以获得元类型的示例:
Int.self
这样的具体类型上调用.self
,这将创建一个static元类型示例Int.Type
。type(of: someInstance)
从任何示例获取dynamic元类型示例。危险区域:
.Protocol
是另一种只存在于协议上下文中的元类型。也就是说,我们无法表达我们只需要P.Type
。这阻止了所有泛型算法与协议元类型一起工作,并可能导致运行时崩溃。对于更多好奇的人:
type(of:)
函数实际上由编译器处理,因为.Protocol
会产生不一致性。hmmo2u0o2#
首先,请在
type(of:)
上查看Apple文档函数签名很有趣:
在哪里使用
如果您正在编写/创建一个接受 type(例如
UIView.Type
)而不接受示例(例如UIView()
)的函数,则应将T.Type
作为参数的类型。它期望的参数可以是:一米四氮一x一米五氮一x一米六氮一x。但是函数为什么需要类型呢?
1.来自表格检视的register函数
请注意,您传递了
CustomTableViewCell.self
。如果稍后您尝试将CustomTableViewCell
类型的tableView出队,但没有注册CustomTableViewCell
类型,则它将崩溃,因为tableView尚未出队/示例化任何CustomTableViewCell
类型的tableView单元格。注意
try decoder.decode(GroceryProduct.self, from: json)
。因为你传递了GroceryProduct.self
,它知道它需要示例化一个GroceryProduct
类型的对象。如果它不能,那么它将抛出一个错误。关于JSONDecoder
的更多信息,请参见well written answer1.尝试查找某个类类型的值。示例尝试在navigationController的所有视图控制器中查找某个类型的视图控制器:
1.作为需要类型的情况的替代解决方法,请参阅以下问题:Swift can't infer generic type when generic type is being passed through a parameter.接受的答案提供了一个有趣的选择。
有关内部组件及其工作原理的更多信息:
.类型
类、结构或枚举类型的元类型是该类型的名称后跟. Type。协议类型的元类型(不是在运行时符合协议的具体类型)是该协议的名称后跟. Protocol。例如,类类型X1 M15 N1 X的元类型是X1 M16 N1 X,并且协议X1 M17 N1 X的元类型是X1 M18 N1 X。
来自苹果:类型
Under the hood
AnyClass
是基本上你在哪里看到
AnyClass
,Any.Type
,AnyObject.Type
,是因为它需要一个类型,一个非常常见的地方是当我们想用register
函数为我们的tableView注册一个类的时候。如果你对“Swift.”做什么感到困惑,那么请参见上面的评论
上述内容也可以写成:
.自我
可以使用 * 后缀 * self表达式将类型作为值访问。例如,SomeClass.self返回SomeClass本身,而不是SomeClass的示例。SomeProtocol.self返回SomeProtocol本身,而不是运行时符合SomeProtocol的类型的示例。可以将
type(of:)
表达式与类型的示例一起使用,以访问该示例的动态、执行阶段型别当做值,如下列范例所示:来自苹果:类型
Playground代码:
简单示例
铁证
我强烈建议阅读苹果关于类型的文档。另请参见here
laawzig23#
它们在语法上出现在不同的位置。
在语法上必须指定类型的地方,
Something.Type
是有效类型,对应于Something
的元类型(类的元类)。Something.self
不是类型的有效语法。从语法上讲,在必须编写表达式的地方,
Something.self
是一个有效的表达式,它是Something.Type
类型的表达式,值是表示Something
类型的东西(在类的情况下是“类对象”)。Something.Type
不是有效的表达式语法。dphi5xsq4#
这是今天把我搞糊涂的主题之一。
我在写一个泛型函数:
试着这样称呼它:
我花了30分钟研究为什么它不工作。然后我尝试了这个:
Xcode的代码完成在显示 meta类型和类型之间的区别方面非常糟糕......从代码完成弹出窗口看起来.self和.Type是一回事:
但是它的“解释像im 5”是,当你有一个Class.Type的方法参数时,它需要一个Class.Type的示例。
self返回Class.Type的示例,而Class.Type引用Class.Type ...
如果你问我的话我很不清楚。
yzuktlbb5#
元类型。类型
Metatype
是一种类型,允许您访问****Class和Struct**About(https://stackoverflow.com/a/59219141/4770877)类型(非示例)的部分内容,如初始化项class和静态About(https://stackoverflow.com/a/59236762/4770877)属性和方法一些实验:
x一个一个一个一个x一个一个二个x
获取字符串