swift进阶十四:Optional & Equatable & 访问控制

swift进阶 学习大纲

上一节,我们介绍了闭包,本节,我们介绍:

  1. Optional
  2. Equatable
  3. Comparable
  4. 访问控制(private、fileprivate、internal、public、open)

1. Optional

Optionalenum结构,包含somenone两个case项。是一个包含nil类型
(所以Optional类型size就是enum大小2个caseenum本身大小为1,加上最大case关联内容(Wrapped类型)大小(如: Optional<String>、Optional<Int>))

public enum Optional<Wrapped>: ExpressibleByNilLiteral {
  case none
  case some(Wrapped)
}

1.1 创建:

// 快捷创建
var age: Int? = 10

// 普通创建
var name: Optional<String> = "ht"
  • 打印结果为Optional类型
    image.png

1.2 使用:

1.2.1 枚举方式
  • 因为Optional本身是enum类型,所以可使用switch模式匹配
var age: Int? = 10

switch age {
case .some(let num):
    print("age为\(num)")
case .none:
    print("值为空")
}
1.2.2 解包

涉及到Optional可选类型,我们就必须解包,因为我们关注的更多是some值

  • 但是每次switch处理,会让我们代码量增大的同时,影响阅读体验(因为我们实际只关心some值)
  • 以下是三种解包方式(推荐第二、第三种):

1. !强解包
非常不建议使用强解包。因为如果遇到nil,程序直接crash

image.png

  • 很多都说使用!强解包,表示程序员对自己的代码足够自信,并愿意承担crash结果
  • 我想说的,真实业务场景下,作为开发者,你必须保证你的代码足够健壮,即便一定不会nil,也不要! 强解包
  • 因为你不确定这份代码逻辑以后会不会被他人改动。所以我建议所有! 强解包的场景,可以选择性使用Assets断言,再使用下面第二第三种方式。

2. if-let

  • if-let 可以配合else使用,也可以直接在if中添加return,表示后续代码都是else场景下,节省了else{},提高代码可读性
var age: Int? = nil

// 可以配合return使用, 省了else的{}
//if let value = age {
//    print("value \(value)")
//    return
//}

if let value = age {
    print("value \(value)")
} else {
    print("age 为 nil")
}

3 guard-let
guard-let是具备守护功能,它必须搭配return使用,排除异常情况,守护guard(作用域)之后的代码

  • guard中的条件,如果不满足,执行guard内的代码后returnguard(作用域)之后的代码,一定是全部满足guard条件的。
    image.png

if-letguard-let使用建议

  • 实际开发过程中,我们希望代码从上至下能清晰表达主线流程

  • guard-let一般用于处理非主线异常情况,直接return出去,守护主线代码。

  • if-let一般用于处理主线重要场景。

if-let创建的内容,仅在if 作用域内可访问。guard-let创建的内容,是供guard 作用域外访问。

2. Equatable

Swift中的类型,可以通过遵循Equatable协议来使用相等运算符(==)不等运算符(!=)

image.png

2.1 绝大多数类型默认实现Equatable协议

image.png

2.2 struct(值类型)

  • 值类型支持直接比较,所以只需要遵循Equatable协议,就自动实现(==)(!=)
    image.png

2.3 class(引用类型)

  • 引用类型需要先遵循Equatable协议,再手动实现(==)(!=)
    image.png

2.4 struct引用类型属性(值类型+引用类型)

  • 值类型中包含引用类型实例。必须实现引用类型Equatable (==)函数,会根据Equatable (==)进行判断:
    image.png

2.5 Optional属性

  • 可选值属性,需要先拓展Optianl==比较方式:
    image.png

2.6 =====

  • == 用来检验是否相等,需要遵循Equatable协议。也就是equal to
  • ===是用来检验两个对象是否是同一个实例对象(内存地址是否相等)。不支持值类型,仅支持类实例(AnyObject?)使用。
@inlinable public func === (lhs: AnyObject?, rhs: AnyObject?) -> Bool
@inlinable public func !== (lhs: AnyObject?, rhs: AnyObject?) -> Bool
image.png

3. Comparable

Comparable协议继承了Equatable协议,并多支持了其他比较方式

public protocol Comparable : Equatable {
    static func < (lhs: Self, rhs: Self) -> Bool
    static func <= (lhs: Self, rhs: Self) -> Bool
    static func >= (lhs: Self, rhs: Self) -> Bool
    static func > (lhs: Self, rhs: Self) -> Bool
}
extension Comparable {
    public static func ... (minimum: Self, maximum: Self) -> ClosedRange<Self>
    @inlinable public static func > (lhs: Self, rhs: Self) -> Bool
    @inlinable public static func <= (lhs: Self, rhs: Self) -> Bool
    @inlinable public static func >= (lhs: Self, rhs: Self) -> Bool
    public static func ..< (minimum: Self, maximum: Self) -> Range<Self>
    prefix public static func ..< (maximum: Self) -> PartialRangeUpTo<Self>
    prefix public static func ... (maximum: Self) -> PartialRangeThrough<Self>
    postfix public static func ... (minimum: Self) -> PartialRangeFrom<Self>
}
image.png

4. 访问控制(private、fileprivate、internal、public、open)

  • OC很少接触这个概念,Swift中针对源文件模块的代码,提供了不同程度访问控制
    访问级别从低到高依次是:
    private<fileprivate<internal<publicopen

  • private: 访问级别仅在当前定义作用域内

class HTPerson {
    private var age = 10
}
HTPerson().age // 访问不到age

利用private权限,我们swift单例正规写法为:

class HTPerson {
    static let sharedInstance = HTPerson()
    private init() {} // 外界无法调用init方法
}
  • filePrivate: 访问级别仅在当前定义文件内
  • Internal: 默认访问级别。允许模块中任意文件访问(模块外不支持访问) (import的都是模块)
  • public: 开放式访问,允许任何模块任何文件访问,但只支持定义模块内继承和子类重写
  • open: 开放式访问,最不受限制,允许任何模块任何文件访问、继承和子类重写

本节知识较简单,所以相关SIL分析没罗列了。Optional访问控制使用频次。下一节,分析协议泛型

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • 1.Optional源码分析和使用 1.1.Optional源码 Optional的本质是enum,所以下面的三种...
    MonKey_Money阅读 235评论 0 0
  • 目录 源文件基础知识文件名文件编码空白字符特殊转义序列不可见的字符和修饰符字符串字面量不可见的字符和修饰符 源文件...
    _小秋_阅读 881评论 0 1
  • 小视频 001--swift简史小视频 002--Playground体验 003--常量&变量 一、swift简...
    谦谦君子修罗刀阅读 6,907评论 8 66
  • 访问控制可以限定其他源文件或模块中代码对你代码的访问级别。你可以明确地给单个类型(类、结构体、枚举)设置访问级别,...
    零度_不结冰阅读 173评论 0 0
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,513评论 16 22