1. selfSelf

1.1 self

大家都知道self关键字在实例方法中指当前对象, 和OC中的作用一样, 但是在OC中在类方法中是无法被使用的,而swift中是可以使用的,接下来我们看看self在这环境下的表示类型。

  • 实例中的self的类型:

在实例方法中self表示的类型是SwiftTestClass_self类型,就是当前类的实例对象

  • 类型中的self


    如上图所示,self的类型显示是SwiftTestClass_self.Type类型,那么。Type是什么类型,字面上来说selfSwiftTestClass_self类型本身

如果我们个类中添加一个静态常量,那么在类方法和今天方法中可以通过self.xxx来访问这个常量,因为他们都属于这个类型本身,self.xxx也就是在访问这个类本身的常量

1.2 Self

1.2.1 实例方法中的Self

Self在实例方法、静态方法、类方法中可以通过Self.xxx来访问静态属性

static let classLet: Int = 0
/// 实例方法
func instanceMethod() -> Void {print("Self.class====\(Self.classLet)")}
/// 静态方法
static func classMethod() -> Void {print("Self.class====\(Self.classLet)")
}
/// 类方法
class func classMethod2() -> Void {print("Self.class====\(Self.classLet)")
}

接下来我们观察下下面代码的代码的打印结果:

static func classMethod() -> Void {print("Self.self====\(Self.self)")print("self====\(self)")print("SwiftTestClass_self.self====\(SwiftTestClass_self.self)")print(Self.self==self)print(SwiftTestClass_self.self == self)print(SwiftTestClass_self.self == Self.self)
}
/**
打印结果:
Self.self====SwiftTestClass_self
self====SwiftTestClass_self
SwiftTestClass_self.self====SwiftTestClass_self
true
true
true
*/

根据官方文档介绍,这个Self的值是等于type(of: self)获取的,也就是这个指是动态获取的

我们看下面示例代码:

static let classLet: Int = 0
/// 可以成功赋值
let instaceLet = classLet
var instaceVar = classLet//let instanceLet2 = self.classLet || Self.classLet 如果使用类中的属性初始化实例中的属性,上面那种赋值是可以的,但是slef.xxx不可以的,会出现编译错误, 因为当前self是未定义的,不存在的lazy var instanceVar2 = Self.classLet
// 如果给懒加载的属性赋值 可以使用Self.xxx,但是不能使用self.xxx, 如果使用懒加载的属性,要注意区分 self 和 Self。因为实例已经完成了初始化,此时 self 是有效的。 此时的self代表当前实例对象, Self代表当前类。你使用类的属性,应该使用类对象,而不是实例对象

1.2.2 协议中的Self

Self用于协议中(Protocol)中限制相关类型(实例加载xib创建的空间实例)

protocol GYLoadNibProtocl {}
// 当这个协议被UIView或者UIView子类使用的时候,默认实现loadFromNib方法,后续实现类可以再进行重写。
//Self 不仅指代的是实现该协议的类型本身,也包括了这个类型的子类
//where Self : UIView : 限制当View和View的子类遵守这个协议之后,默认有实现 loadFromNib这个方法
extension GYLoadNibProtocl where Self : UIView {//在协议里面不允许定义class 只能定义staticstatic func loadFromNib(_ nibname: String? = nil) -> Self {//Self (大写) 当前类对象//self(小写) 当前对象let loadName = nibname == nil ? "\(self)" : nibname!return Bundle.main.loadNibNamed(loadName, owner: nil, options: nil)?.first as! Self}
}

Self用于类(Class)的返回值

protocol TestProtocol {func getSelf() -> Self
}class TestSubClass: TestProtocol {var name = "ceshi"//作为类的返回值class func getInstance() -> Self {return TestSubClass() as! Self}func getInstance2() -> Self {return TestSubClass() as! Self}
}
//此时Self是最终实现协议的那个类型
let sub = TestSubClass()
print(sub)
let sub2 = TestSubClass.getInstance()
print("sub2.name=====\(sub2.name)")

2. =====的区别

2.1 ==的应用

  • ==:是Equatable协议中定义的方法,它的否定形式!=,支持自定义比较,规则可以由开发者自行定义比较规则
//关于此协议可以点击api查看具体的介绍
public protocol Equatable {/// Returns a Boolean value indicating whether two values are equal.////// Equality is the inverse of inequality. For any values `a` and `b`,/// `a == b` implies that `a != b` is `false`.////// - Parameters:///   - lhs: A value to compare.///   - rhs: Another value to compare.static func == (lhs: Self, rhs: Self) -> Bool
}

我们可以自定义一个类,然后遵守此协议实现比较方法:

//定义一个学生类,声明两个属性
class Student: NSObject {var name: Stringvar age: Intinit(name: String, age: Int) {self.name = nameself.age = age}//自定义对象,想要比较两个对象是否相等, 那么需要实现isEqual方法 实现比较规则你 猜测”==“的底层是调用isEqual方法, 而isEqual方法可能和hash值有关/**/// Subclasses of `NSObject` can customize Equatable conformance by overriding/// `isEqual(_:)`. If two objects are equal, they must have the same hash/// value, so if you override `isEqual(_:)`, make sure you also override the `hash` property.NSObject的子类 如果想自定义比较,需要重写isEqual(_:)方法。如果两个对象比较,他们必须有一个相同的hash值,因此你必须重写isEqual(_:), 并确认你也重写hash属性*/override func isEqual(_ object: Any?) -> Bool {if object == nil {return false}//is  相当于OC中的isKindof方法,判断是否是某个类或则子类的实例if object is Student {let obj = object as! Studentreturn name==obj.name && age == obj.age} else {return false}}//经过实践 如果不实现这个属性 只要重写isEqual(_:) 这个方法也可以比较两个对象override var hash: Int {return self.hash}
}let student = Student.init(name: "guo", age: 22)
let student1 = Student.init(name: "guo", age: 22)
//如果Student 不是继承是NSObject,并且没有遵守Equatable协议 是无法使用”==“ 来比较两个student对象的,如果集成NSObject,那就可以使用”==“来比较,
print("比较两个数=======\(student==student1)")//打印结果: true

如果自定义的类不是集成NSObject,而是遵循Equatable是什么情况了

class Person: Equatable {//需要重写== 方法static func == (lhs: Person, rhs: Person) -> Bool {return lhs.name==rhs.name && lhs.age==rhs.age}var name: Stringvar age: Intinit(name: String, age: Int) {self.name = nameself.age = age}
}let person = Student.init(name: "guo", age: 22)
let person1 = Student.init(name: "guo", age: 22)
print("比较两个数=======\(person==person1)")
//打印结果: true

如果是直接遵守Equatable协议的,那么需要实现协议方法static func == (lhs: Person, rhs: Person) -> Bool {},可以直接在这个方法中实现自定义的比较规则,然后就可以标记两个对象了

2.2 ===的应用

  • ===:比较的是指针,所以只能比较引用类型,否定形式!==,不支持开发者自定义规则

self和Self、== 和===的区别相关推荐

  1. RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别

    1. 基本概念 PRC 远程过程调用 Remote Procedure Call,其就是一个节点请求另外一个节点提供的服务.当两个物理分离的子系统需要建立逻辑上的关联时,RPC 是牵线搭桥的常见技术手 ...

  2. C++ 笔记(28)— C++ 中 NULL和 nullptr 的区别

    最近看公司代码的时候发现在判断指针是否为空的时候,有的时候用的是 NULL, 有的时候用的是 nullptr 感觉很奇怪,好奇心驱使我查了下两者的区别,发现还是有很多细节需要学习的. 1. NULL ...

  3. gcc 和 g++ 的联系和区别,使用 gcc 编译 c++

    GCC 编译器已经为我们提供了调用它的接口,对于 C 语言或者 C++ 程序,可以通过执行 gcc 或者 g++ 指令来调用 GCC 编译器. 实际使用中我们更习惯使用 gcc 指令编译 C 语言程序 ...

  4. Python2 与 Python3 区别

    Python2.x 与 Python3.x 区别 1. print 函数 Python2 中 print 是语句(statement),Python3 中 print 则变成了函数.在 Python3 ...

  5. Docker 入门系列(1)- 初识容器,镜像、容器、仓库的区别

    Docker 简介 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发 ...

  6. HTTP 协议入门 — (TCP/IP协议族、通信传输流、URI 与 URL 的区别、Cookie 状态管理、HTTP 支持的方法、状态码类别、HTTP 首部字段)

    TCP/IP协议族 在介绍 HTTP 协议之前,我们先对 TCP/IP 协议族有个大概的了解,TCP/IP 协议从上到下主要分为应用层.传输层.网络层和数据链路层,各层的主要功能如下表所示: 协议层 ...

  7. python二进制打开(rb)和文本格式打开(r)什么区别?

    使用 open() 函数以文本格式打开文件和以二进制格式打开文件,唯一的区别是对文件中换行符的处理不同. 在 Windows 系统中,文件中用 "\r\n" 作为行末标识符(即换行 ...

  8. python中__dict__与dir()区别

    前言 Python下一切皆对象,每个对象都有多个属性(attribute),Python对属性有一套统一的管理方案. __dict__与dir()的区别: dir()是一个函数,返回的是list: _ ...

  9. java和C#面向对象的区别

    问题:C#中的构造函数和java的构造函数一样吗? 答: .net的项目中,写实体Entity属性时,经常会为每一个属性写一对get和set方法,在用到这个实体或是一个类时,通过new实例化一个对象, ...

  10. 判别模型和生成模型的区别

    20210703 https://www.zhihu.com/question/20446337 机器学习"判定模型"和"生成模型"有什么区别? 重点 http ...

最新文章

  1. 秒抢红包的背后,是复杂的即时付款系统
  2. python难度大的题_早看少被坑!Python 最难的问题
  3. 攻击者怎样使用HTML和CSS隐藏“外部发件人”电子邮件警告
  4. RPM 软件包默认的安装路径
  5. 数据库-MySQL-JDBC-结果集
  6. 用python海龟画一个三角形_海龟画笔---和孩子一起学python
  7. 使用eclipse导入spring-framework-5.0.x源码
  8. 鸿蒙系统屏幕录制,鸿蒙系统游戏性能出色;三星折叠屏发布屏下摄像头
  9. 北京总体城市设计战略研究│成果
  10. 算法专题训练(1)股票问题
  11. 广义相对论 的 一个问题
  12. 机器阅读理解论文必读论文(二): Teaching Machines to Read and Comprehend
  13. H264系列(5):关于ITU-H264 和 ISO/IEC H264 的关系
  14. 用javascript统计字数,中文计数问题
  15. 第一次暑假实习面试,进入二面就算成功(没有成功)
  16. 保姆级教程带你在VMware中安装Linux Debinan操作系统
  17. python控制机器人走直线_python程序控制NAO机器人行走
  18. oracle授权查询
  19. More Effective C++之 Item M35:让自己习惯使用标准C++语言
  20. Mysql中的通用表达式WITH AS语句的使用

热门文章

  1. 栈,队列和链表三者之间的关系与区别
  2. 单点登录(Single Sign On)解决方案
  3. 51单片机用c语言倒计时程序,51单片机实现100以内倒计时,求大佬指点。
  4. Stata: 面板 Granger 因果检验
  5. 数据结构实验-稀疏一元多项式计算
  6. 移动直播明争暗战五年:人性、梦想与资本的碰撞
  7. 记录Linux下安装elasticSearch时遇到的一些错误
  8. TIME_WAIT详解
  9. graphql_GraphQL简介
  10. vue封装请求 获取上传文件进度及设置超时时间