透过Boolean看Swift

一个简单的Bool类型内部就包含了许多Swift主要功能, 如何构建一个简单类型是有趣的演示. 本文将创建一个与Bool类型在设计与实现上非常相似的新MyBool类型.我们希望通过设计和实现一个简单的Swift类型能让你更好的理解Swift语言是如何工作的.

enum MyBool {
case myTrue, myFalse
}

让我们从基本的定义开始. MyBool类型有两种不同状态, 用enum来实现

extension MyBool {
init() { self = .myFalse }
}

为了不误解,我们命名状态为 myTrue 和 myFalse. 我们希望 MyBool() 默认为false值, 因此我们实现一个 init 方法:
Swift enum 声明隐含了枚举值的有效范围, 它允许我们使用 MyBool.myFalse 甚至是在环境类型允许时可以使用 .myFalse. 然而, 我们需要我们的类型可以用 true 和 false 常量赋值. 要实现它, 我们让 MyBool 实现 BooleanLiteralConvertible 协议:
extension MyBool : BooleanLiteralConvertible {

extension MyBool : BooleanLiteralConvertible {
static func convertFromBooleanLiteral(value: Bool) -> MyBool {
return value ? myTrue : myFalse
}
} //就样,我们就可以把'true'和'false'赋给MyBool
var a : MyBool = true

这一步完成, 我们就有了基础类型, 但是我们做的事情还不够. Booleans 需要用于 if 条件判断. Swift用 BooleanType 协议来实现它, 它使任意类型都可以用于逻辑条件:

extension MyBool : BooleanType {
var boolValue: Bool {
switch self {
case .myTrue: return true
case .myFalse: return false
}
}
} // 现在MyBool可以用于 'if' 各 'while' 条件判断.
if a {}

我们同样希望所以符合 BooleanType 协议的变量可以转换到MyBool, 所以我们加上

extension MyBool {
// MyBool可以通过BooleanType构造
init(_ v : BooleanType) {
if v.boolValue {
self = .myTrue
} else {
self = .myFalse
}
}
} // 现在可以将 boolean-like 类型.
var basicBool : Bool = true
a = MyBool(basicBool)

注意, 在初始化参数中使用 _ 来禁用参数关键字, 它允许使用 MyBool(x) 语法来替代默认的 MyBool(v: x).
现在我们有了基本的功能, 下面我们从 == 开始定义一些操作符. 编译器并没有使简单的枚举自动 Equatable, 因此还需要额外的代码. 这里, 你可以实现 Equatable 协议和 == 操作符来实现任意类型进行相等比较. 如果 MyBool还没有 Equatable, 可以实现如下:

extension MyBool : Equatable {
} func ==(lhs: MyBool, rhs: MyBool) -> Bool {
switch (lhs, rhs) {
case (.myTrue,.myTrue), (.myFalse,.myFalse):
return true
default:
return false
}
} // 现在可以用 == 和 != 比较
if a == a {}
if a != a {}

这里我们在switch语句中用一些简单的模式匹配来处理. 既然 MyBool 已经 Equatable, 我们就不用再实现 != 操作符. 下面我们加入二进制操作:

func &(lhs: MyBool, rhs: MyBool) -> MyBool {
if lhs {
return rhs
}
return false
} func |(lhs: MyBool, rhs: MyBool) -> MyBool {
if lhs {
return true
}
return rhs
} func ^(lhs: MyBool, rhs: MyBool) -> MyBool {
return MyBool(lhs != rhs)
}

使用基本的操作符, 我们可以实现其它有用的一元和组合赋值符, 例如:

prefix func !(a: MyBool) -> MyBool {
return a ^ true
} // 组合赋值
func &=(inout lhs: MyBool, rhs: MyBool) {
lhs = lhs & rhs
}

在 &= 操作符中, 因为左值需要修改值, 我们为参数加上 inout 修饰符. 对值类型(如enum和struct), Swift为你提供了完整的修改操作控制.

通过这些, 简单 MyBool 类型有了所有的基本操作和操作符. 希望本文的提示可以为定义高级类型提供参考.

来自:苹果官方博客2014-8-5 Boolean

后记:

麻雀虽小, 五脏俱全. Swift通过协议和操作符定义, 让我们的代码更加美妙.

iOS: 学习笔记, 透过Boolean看Swift(译自: https://developer.apple.com/swift/blog/ Aug 5, 2014 Boolean)的更多相关文章

  1. iOS: 学习笔记, 值与引用类型(译自: https://developer.apple.com/swift/blog/ Aug 15, 2014 Value and Reference Types)

    值和引用类型 Value and Reference Types 在Swift中,有两种数据类型. 一是"值类型"(value type), 它是每一个实例都保存有各自的数据,通常 ...

  2. iOS学习笔记-自定义过渡动画

    代码地址如下:http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swif ...

  3. IOS学习笔记25—HTTP操作之ASIHTTPRequest

    IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...

  4. iOS学习笔记-精华整理

    iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...

  5. iOS学习笔记总结整理

    来源:http://mobile.51cto.com/iphone-386851_all.htm 学习IOS开发这对于一个初学者来说,是一件非常挠头的事情.其实学习IOS开发无外乎平时的积累与总结.下 ...

  6. iOS学习笔记之ARC内存管理

    iOS学习笔记之ARC内存管理 写在前面 ARC(Automatic Reference Counting),自动引用计数,是iOS中采用的一种内存管理方式. 指针变量与对象所有权 指针变量暗含了对其 ...

  7. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  8. IOS学习笔记06---C语言函数

    IOS学习笔记06---C语言函数 --------------------------------------------  qq交流群:创梦技术交流群:251572072              ...

  9. [置顶] iOS学习笔记47——图片异步加载之EGOImageLoading

    上次在<iOS学习笔记46——图片异步加载之SDWebImage>中介绍过一个开源的图片异步加载库,今天来介绍另外一个功能类似的EGOImageLoading,看名字知道,之前的一篇学习笔 ...

随机推荐

  1. svn 被锁定

    遇到svn被锁定,clearup 不管用一直报错 用命令行解决了 问题 : command line -> cmd>svn help>svn cleanup>exit

  2. SQL 中having 和where的区别分析

    在select语句中可以使用groupby子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句限制返回的结果集 在select语句中可以使用groupby子 ...

  3. ARCGIS获取图层下的要素信息及要素类转换为要素

    /// <summary> /// 得到需要的字段名和字段值 /// </summary> /// <param name="layer">&l ...

  4. 插入ts以及判断列是否存在(支持多数据库)

    1:增加ts.dr字段,先判断ts.dr字段是否存在,其中ts字段插入的是日期,默认值为当前插入的时间,dr字段是数值型,默认值为0 * 增加ts/dr字段 * * @param tableList ...

  5. 如何让MFC程序关闭按钮失效,也无法右击任务栏关闭窗口来关闭?

    如何让MFC程序关闭按钮失效,也无法右击任务栏关闭窗口来关闭,即右键任务栏的关闭窗口失效呢?很简单,有一个小窍门就是:响应IDCANCEL消息,具体实现如下: 首先定义消息映射:ON_BN_CLICK ...

  6. 能发送http请求(get,post)的工具

    能发送http请求(get,post)的工具, 1.  fiddler 前端自己模拟发送请求 2.  其他 链接:https://www.zhihu.com/question/20367546/ans ...

  7. Ubuntu16.04下Intellij IDEA不能输入中文的问题

    最近Ubuntu升级到16.04后发现IDEA的中文输入法不能正常切换了. 之前用的是fcitx安装的输入法, 折腾了半天才解决. 只需要修改idea.sh文件即可. 不需要折腾fcitx中的配置. ...

  8. apache安全之修改或隐藏版本信息

    修改apache版本信息    在安装之前,编辑原文件httpd-2.2.31/include/ap_release.h文件如下:     40 #define AP_SERVER_BASEVENDO ...

  9. C#面向对象(二)

    一:抽象方法 1. 在面向对象编程语言中抽象方法指一些只有方法声明,而没有具体方法体的方法.抽象方法一般存在于抽象类或接口中. 在一些父类中,某些行为不是非常明确,因此无法用代码来具体实现,但是类还必 ...

  10. JOSN学习总结<二> JSON的格式与语法

    今晚又下班早!!嘿嘿,继续JOSN的总结吧!!!!有人说这么简单还有必要写吗???我觉得“眼里过十遍不如手里过一遍”!!有错误之处请指正!!共同学习下!!!!废话不说了,进入今晚的正题: <二& ...