swift中的self,Self,Class(struct).Type让你头大了嘛?

讲解这一部分,不区分大小写就是耍流氓 ``self(首字母小写)``self是Swift 中最简单和最常见的。它后面通常跟一个.和一个属性或函数名称。

ini 复制代码
self.name = "Joke" 
self.test()

self是类(或结构体)中对当前对象也就是"实例"的引用 接下来看下在类方法或者说静态方法中小写self是什么

Swift 中的元类型用 .Type 表示。比如 Int.Type 就是 Int 的元类型。类型与值有着不同的形式,就像 Int 与 5 的关系。元类型也是类似,.Type 是类型,类型的 .self 是元类型的值。例如可以像下边这样定义

swift 复制代码
let intMetatype: Int.Type = Int.self

Self(首字母大写)

在 Swift 中,Self指的是一种类型------通常是当前上下文中的当前类型。正如小写self可以表示当前对象,大写Self可以表示当前类型。在定义协议的时候Self 用的频率很高

在协议中,它是指在任何特定用途中符合该协议的类型。

swift 复制代码
extension Numeric {    
    func squared() -> Self {        
        return self * self    
    }
}
2.squared() //这里的2是整数
2.0.squared() //这里的2.0是double

在此上下文中,Self指的是符合Numeric协议的类型。在示例中2去调用则Self将是具体类型Int。如果是2.0则Self将是具体类型Double

如果要限制具体类型则在extension使用Self配合我们之前说的where

sql 复制代码
extension Numeric where Self == Int {    
    func squared() -> Self {        
        return self * self    
    }
}
2.squared() 
2.0.squared() //Referencing instance method 'squared()' on 'Numeric' requires the types 'Double' and 'Int' be equivalent

从上边的例子也可以看出,在静态方法或者对象方法中,都可以作为返回类型。表示返回类型是方法所在的类的类型,而不是方法声明所在的类的类型。它类似于 OC 中的instancetype

swift 复制代码
class Base {    
    // 返回类型是 Base    
    func create() -> Base {        
        return Base()    
    }    
    // 返回类型是 Self    
    func createSelf() -> Self {        
        return self    
    }
}
class Subclass: Base {    
    // 返回类型是 Subclass    
    override func create() -> Base {        
        return Subclass()    
    }    
    // 返回类型是 Subclass    
    override func createSelf() -> Self {        
        return self    
    }
}

可以说Self就是为继承和协议而生的,我们来看下边的错误

swift 复制代码
class Cat {    
    var age : Int = 0    
    func meow(){        
        print("(self) 喵喵喵!")    
    }        
    func makeNewCat() -> Self{        
        return Cat()//Cannot convert return expression of type 'Cat' to return type 'Self'        
        return self //正确    
    }
}

这个错误是因为 Self 类型需要返回实际的当前类型实例,而不是基类 Cat 的实例。这里有点难理解,想象Cat被继承后,在子类对象上调用makeNewCat,返回值类型为Self,也就是子类,但是实际返回的是Cat,这个冲突就是这里报错的关键而且即便当前方法是static的,也会有相同的错误提示,可见同是否为类方法没有关系,而是与Self本身的设计相关咱再看另外一个问题

scss 复制代码
func meow() -> type(of: self) { //报错:Cannot find type 'type' in scope        
    print("(self) 喵喵喵!")        
    type(of: self)        
    return Cat()    
}

这个错误是因为Swift 是静态类型语言,函数的返回类型必须在编译时明确指定,而 type(of:) 的返回值是运行时动态确定的(取决于传入的实例),编译时无法预知其具体类型。另外还有更重要的原因:

swift 复制代码
public func type<T, Metatype>(of value: T) -> Metatype

这个type(of: )方法返回的是元类型,但函数声明需要具体的类型名称类方法中的self 和 大写的Self 以及类.self什么关系?

c语言中一个类型标明了其对象存储需要的内存大小等信息因此所有的值都应该有一个类型,而静态属性和类方法存在于某class上,所以在这种情况下,某class.self 就拥有了一种类型:Self.Type。比如:Dog.Type 就保存所有 Dog 的类型值。这里可能有点别扭,我们平时说的某class其实是一个对象,如果要获取这个对象需要用某class.self来获取首先看下类方法中的self和Dog.self的关系

swift 复制代码
class Dog {    
    class func bark() {        
        print("(self) 汪汪汪!")     
    }    
    func instanceBark(){        
        if Dog.self == Self.self{            
            print("(Self.self) 汪汪汪!")        
        }    
    }
}

在类方法中打一个断点,注意打印的时候用p,而不是po,po 打印出来都是sort.Dog,也就是类对象本身

less 复制代码
p self
(@thick sort.Dog.Type) @thick sort.Dog.Type
p Dog.self
(sort.Dog.Type) sort.Dog.Type

可见类方法中的self和Dog.self是同一种对象,其实它们是同一个对象,也就是Dog这个类自身(好难说清楚,如果你读完本文很困惑,可以私信我)可能至此你觉得"我懂了",但是请看这个:

self.name 类的属性可以取到nnn没什么问题但是为什么Self.name也可以取到?看这个打印结果貌似self 和Self相同呀,但是怎么解释下边这个呢?

Self在这里等同于Dog,我们的self是Dog对应的类对象,注意这里类对象和类的关系,因此应该用Self.self 和self比较(这里真的很绕)

关键概念区分

1、类 (Class)

  1. 是类型(Type),存在于编译器的类型系统中

  2. 逻辑概念,不是内存中的具体实体

  3. 例如:class Dog {}中的 Dog、上述代码中的Self

2、元类型 (Metatype)

  1. 是类型的类型,描述类本身的结构

  2. 在Swift中表示为 SomeClass.Type

  3. 例如:Dog的元类型是 Dog.Type元类型实例 (Metatype Instance)

3、是元类型的具体实例

  1. 存在于运行时内存中

  2. 通过 .self获取,如 Dog.self、Self.self

  3. 本质是一个指向类元数据的指针

最后看个用法

swift 复制代码
let dogType: Dog.Type = Labrador.self //Labrador是我们定义的Dog的子类
func saySomething(dog: Dog.Type) {    
    print("(dog) 汪汪汪!")
}
saySomething(dog: dogType) // Labrador 汪汪汪!

docs.swift.org/swift-book/...

相关推荐
游戏开发爱好者818 小时前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
黑码哥19 小时前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
2501_9151063220 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview
2501_9151063220 小时前
使用 Sniffmaster TCP 抓包和 Wireshark 网络分析
网络协议·tcp/ip·ios·小程序·uni-app·wireshark·iphone
熊猫钓鱼>_>21 小时前
移动端开发技术选型报告:三足鼎立时代的开发者指南(2026年2月)
android·人工智能·ios·app·鸿蒙·cpu·移动端
徐同保2 天前
通过ip访问nginx的服务时,被第一个server重定向了,通过设置default_server解决这个问题
ios·iphone
2501_915918412 天前
在 iOS 环境下查看 App 详细信息与文件目录
android·ios·小程序·https·uni-app·iphone·webview
2501_916007472 天前
没有 Mac 用户如何上架 App Store,IPA生成、证书与描述文件管理、跨平台上传
android·macos·ios·小程序·uni-app·iphone·webview
夏幻灵2 天前
HTTPS全面解析:原理、加密机制与证书体
ios·iphone
TheNextByte13 天前
如何在iPhone上恢复已删除的笔记的综合指南
笔记·ios·iphone