Swift 中的 Self & Self.Type & self
Swift 中的 Self & Self.Type & self
这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战
你可能在写代码的时候已经用过很多次 self 这个关键词了,但是你有没有想过什么是 self 呢?今天我们就来看看:
- 什么是 self、Self 和 Self.Type?
- 都在什么情况下使用?
self
这个大家用的比较多了,self 通常用于当你需要引用你当前所在范围内的对象时。所以,例如,如果在 Rocket 的实例方法中使用 self,在这种情况下,self 将是该 Rocket 的实例。这个很好理解~
struct Rocket {
func launch() {
print("10 秒内发射 \(self)")
}
}
let rocket = Rocket()
rocket.launch() //10 秒内发射 Rocket()
但是,如果要在类方法或静态方法中使用 self,该怎么办?在这种情况下,self 不能作为对实例的引用,因为没有实例,而 self 具有当前类型的值。这是因为静态方法和类方法存在于类型本身而不是实例上。
class Dog {
class func bark() {
print("\(self) 汪汪汪!")
}
}
Dog.bark() //Dog 汪汪汪!
struct Cat {
static func meow() {
print("\(self) 喵喵喵!")
}
}
Cat.meow() // Cat 喵喵喵!
元类型
还有个需要注意的地方。所有的值都应该有一个类型,包括 self。就像上面提到的,静态和类方法存在于类型上,所以在这种情况下,self 就拥有了一种类型:Self.Type。比如:Dog.Type 就保存所有 Dog 的类型值。
包含其他类型的类型称为元类型。
有点绕哈,简单来说,元类型 Dog.Type 不仅可以保存 Dog 类型的值,还可以保存它的所有子类的值。比如下面这个例子,其中 Labrador 是 Dog 的一个子类。
class Dog {
class func bark() {
print("\(self) 汪汪汪!")
}
}
class Labrador: Dog {
}
Labrador.bark() //Labrador 汪汪汪!
如果你想将 type 本身当做一个属性,或者将其传递到函数中,那么你也可以将 type 本身作为值使用。这时候,就可以这样用:Type.self。
let dogType: Dog.Type = Labrador.self
func saySomething(dog: Dog.Type) {
print("\(dog) 汪汪汪!")
}
saySomething(dog: dogType) // Labrador 汪汪汪!
Self
最后,就是大写 s 开头的 Self。在创建工厂方法或从协议方法返回具体类型时,非常的有用:
struct Rocket {
func launch() {
print("10 秒内发射 \(self)")
}
}
extension Rocket {
static func makeRocket() -> Self {
return Rocket()
}
}
protocol Factory {
func make() -> Self
}
extension Rocket: Factory {
func make() -> Rocket {
return Rocket()
}
}