透过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. 使用泛型简单封装NGUI的ScrollView实现滑动列表

    懒,是老毛病了,周末跑了半马,跑完也是一通累,好久没锻炼了..也是懒的,有时都懒的写博客..最近看到项目中各种滑动列表框,本着要懒出水平来的原则,决定花点时间简单处理下(暂时未做列表太多时的优化):1 ...

  2. Jupyter Notebook PDF输出的中文支持

    Jupyter Notebook是什么 Jupyter Notebook是ipython Notebook 的升级.Jupyter能够将实时代码,公式,可视化图表以Cell的方式组织在一起,形成一个对 ...

  3. git 命令归纳

    git 新手一枚,随用随更新 git clone git@example.com:project-name.git 克隆 git branch [-a -r] 查看分支[所有 远端] git pull ...

  4. 备战“软考”之软件project

    说到"软件project"就有一种非常纠结的感觉!为什么呢?由于刚进入软考复习阶段,大家都把它放到了"比較"次要的地位,由于已经学过两遍,再加上它没有非常难理解 ...

  5. CentOS Nginx+jdk+tomcat 环境搭建

    一.jdk安装 jdk下载地址:http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloa ...

  6. Android保存设置的PreferenceActivity

    界面XML文件:preference_setting.xml <?xml version="1.0" encoding="UTF-8"?> < ...

  7. 在命令行中如何访问Program Files文件夹(转)

    通常来说Program Files文件夹位于C盘,也就是C:\Program File.为了保证兼容性,在命令行中通常使用环境变量%ProgramFiles%来表示Program Files的具体路径 ...

  8. 会话技术之Cookie 和 Session

    为什么要使用会话技术 会话从字面上来说就是,就是两个人说话,也就是两个人交流,那么这里说的是计算机web端的交流,因为互联网是基于HTTP传输信息的,而http传输是无状态协议,缺少状态,意味着如果后 ...

  9. [上传下载] C#修改DownLoadHelper上传下载帮助类 (转载)

    点击下载 DownLoadHelper.rar 主要功能如下 /// <summary> /// 输出硬盘文件,提供下载 支持大文件.续传.速度限制.资源占用小 /// </summ ...

  10. 1.RABBITMQ 入门 - WINDOWS - 获取,安装,配置

    一. 背景:     公司项目有所改动,要求微信(移动端调用的接口),日志接口换位log4net,全部改成以rabbitMQ作为服务支持, 二.本地环境:     windows 10 enterpr ...