swift self Self 使用
前言
swift 真是奇幻,一个 self 有一堆用法,当然这都是必要的,还有他 Self 。看的我眩晕,在网上搜集了不少,再加上自己的实践理解,记录如下。 其实,花点时间仔细理解下很好区分的。
self 表示自己
- 多用在在方法内部,如果不写,xcode 会提醒,大家一看就明白,我们也常用
init(a: Int, b: Int) {
self.a = a
self.b = b
}
- 在某个实例后面取得这个实例本身
.self可以用在类型后面取得类型本身,也可以用在某个实例后面取得这个实例本身。前一种方法可以用来获得一个表示该类型的值,这在某些时候会很有用; 而后者因为拿到的实例本身,所以暂时似乎没有太多需要这么使用的案例。
表示类型 (.Typle 的实例)元数据 官网
class SomeBaseClass {
class func printClassName() {
print("SomeBaseClass")
}
}
class AnotherSubClass: SomeBaseClass {
let string: String
required init(string: String) {
self.string = string
}
override class func printClassName() {
print("AnotherSubClass")
}
}
let metatype: AnotherSubClass.Type = AnotherSubClass.self
let anotherInstance = metatype.init(string: "some string")
AnotherSubClass.self
代表具体类型, 元数据类的实例
AnotherSubClass.Type
代表 AnotherSubClass 类型。 元数据类
表达不清楚,细细品味下就懂我意思了
区分type(of: someInstance) 注意是运行时具体的元类型
class SomeSubClass: SomeBaseClass {
override class func printClassName() {
print("SomeSubClass")
}
}
let someInstance: SomeBaseClass = SomeSubClass()
// The compile-time type of someInstance is SomeBaseClass,
// and the runtime type of someInstance is SomeSubClass
type(of: someInstance).printClassName()
// Prints "SomeSubClass"
.self is what Apple calls a static metatype a fancy word for what is the compile time type of an object.
On the other hand, type(of) will return a dynamic metatype, which is the metatype of the object's real, runtime type.
Self 关键字用在类里, 作为函数返回值类型, 表示当前类。
class ClassA {
var a: Int
var b: Int
init(a: Int, b: Int) {
self.a = a
self.b = b
}
@discardableResult
func setValueA(param: Int) -> Self {
self.a = param
return self
}
@discardableResult
func setValueB(param: Int) -> ClassA {
self.b = param
return self
}
}
let objA = ClassA(a: 1, b: 2)
objA.setValueA(param: 3)
objA.setValueB(param: 4)
print("a:\(objA.a),b:\(objA.b)")
这段代码里有self和Self, self指向类自身;Self只能作为函数关键字, setValue函数的返回值是ClassA类型 ClassA 和 Self 等价
Swift 如何构建一个Self类型的对象
//构建一个Self类型对象
func copy() -> Self {
/* 如果我们写成 let result = ClassA(a: 1, b: 2)
这样编译是不通过的, 这里我们就需要用 type它来做初始化了
*/
let result = type(of: self).init(a: 1, b: 1)
return result
}
但是这样做是可以的
func copy() -> ClassA {
let result = ClassA(a: 1, b: 2)
return result
}
Swift 4.2 可以使用 self 做为变量名
在 4.2 之前,self 是全局保留关键字
现在 otional binding 中 self 不再作为保留关键字。
补充
发现和associatedtype
联合使用。目前,我没找到官方的解释。 就自以为的解释下
比如 Collection 头文件的部分源码
public protocol Collection : Sequence where Self.SubSequence : Collection {
associatedtype Element
/// A type that represents a position in the collection.
///
/// Valid indices consist of the position of every element and a
/// "past the end" position that's not valid for use as a subscript
/// argument.
associatedtype Index : Comparable where Self.Index == Self.Indices.Element, Self.Indices.Element == Self.Indices.Index, Self.Indices.Index == Self.SubSequence.Index, Self.SubSequence.Index == Self.Indices.Indices.Element, Self.Indices.Indices.Element == Self.Indices.Indices.Index, Self.Indices.Indices.Index == Self.SubSequence.Indices.Element, Self.SubSequence.Indices.Element == Self.SubSequence.Indices.Index, Self.SubSequence.Indices.Index == Self.SubSequence.Indices.Indices.Element, Self.SubSequence.Indices.Indices.Element == Self.SubSequence.Indices.Indices.Index
/// The position of the first element in a nonempty collection.
///
/// If the collection is empty, `startIndex` is equal to `endIndex`.
public var startIndex: Self.Index { get }
看最简单的 public var startIndex: Self.Index { get }
这里的 Self 指具体的实现了Collection协议的类。Index 就 泛型 对应的那个 Index。合起来就是一个具体的类型(Self.Index)。有些类似(var Index: Int 中的Int) 这样的就对 startIndex 的类型做了限定。