swift self Self 使用

2019-01-21  本文已影响0人  jianshudxw

前言

swift 真是奇幻,一个 self 有一堆用法,当然这都是必要的,还有他 Self 。看的我眩晕,在网上搜集了不少,再加上自己的实践理解,记录如下。 其实,花点时间仔细理解下很好区分的。

self 表示自己

  1. 多用在在方法内部,如果不写,xcode 会提醒,大家一看就明白,我们也常用
    init(a: Int, b: Int) {
        self.a = a
        self.b = b
    }
  1. 在某个实例后面取得这个实例本身

.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 的类型做了限定。

参考

Swift3.0 Self和self的区别
Swift 如何构建一个Self类型的对象

上一篇下一篇

猜你喜欢

热点阅读