透过Boolean看Swift

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

  1. enum MyBool {
  2. case myTrue, myFalse
  3. }

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

  1. extension MyBool {
  2. init() { self = .myFalse }
  3. }

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

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

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

  1. extension MyBool : BooleanType {
  2. var boolValue: Bool {
  3. switch self {
  4. case .myTrue: return true
  5. case .myFalse: return false
  6. }
  7. }
  8. }
  9.  
  10. // 现在MyBool可以用于 'if' 各 'while' 条件判断.
  11. if a {}

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

  1. extension MyBool {
  2. // MyBool可以通过BooleanType构造
  3. init(_ v : BooleanType) {
  4. if v.boolValue {
  5. self = .myTrue
  6. } else {
  7. self = .myFalse
  8. }
  9. }
  10. }
  11.  
  12. // 现在可以将 boolean-like 类型.
  13. var basicBool : Bool = true
  14. a = MyBool(basicBool)

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

  1. extension MyBool : Equatable {
  2. }
  3.  
  4. func ==(lhs: MyBool, rhs: MyBool) -> Bool {
  5. switch (lhs, rhs) {
  6. case (.myTrue,.myTrue), (.myFalse,.myFalse):
  7. return true
  8. default:
  9. return false
  10. }
  11. }
  12.  
  13. // 现在可以用 == 和 != 比较
  14. if a == a {}
  15. if a != a {}

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

  1. func &(lhs: MyBool, rhs: MyBool) -> MyBool {
  2. if lhs {
  3. return rhs
  4. }
  5. return false
  6. }
  7.  
  8. func |(lhs: MyBool, rhs: MyBool) -> MyBool {
  9. if lhs {
  10. return true
  11. }
  12. return rhs
  13. }
  14.  
  15. func ^(lhs: MyBool, rhs: MyBool) -> MyBool {
  16. return MyBool(lhs != rhs)
  17. }

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

  1. prefix func !(a: MyBool) -> MyBool {
  2. return a ^ true
  3. }
  4.  
  5. // 组合赋值
  6. func &=(inout lhs: MyBool, rhs: MyBool) {
  7. lhs = lhs & rhs
  8. }

在 &= 操作符中, 因为左值需要修改值, 我们为参数加上 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. Spring基于注解的Cache支持

    Spring为我们提供了几个注解来支持Spring Cache.其核心主要是@Cacheable和@CacheEvict.使用@Cacheable标记的方法在执行后Spring Cache将缓存其返回 ...

  2. 蜗牛—JSP学习之JavaBean初识

    初识: <%@ page language="java" import="java.util.*" pageEncoding="utf-8&qu ...

  3. requireJS(二)

    一.前言 requireJS(一) 本篇主要整理requirejs的一些用法,相对比较零散. 实例目录 二.优化 requirejs建议我们给每一个模块书写一个js文件.但是这样会增加网站的http请 ...

  4. windows mysql 中文乱码和中文录入提示太大错误的解决方法

    今天操作mysql的时候很郁闷,因为修改默认字符集搞了半天,终于弄成了(关于如何把windows的默认字符集设置成功,可以参看另一篇博文,最终在mysql中输入show variables like ...

  5. JDBC Transaction Management Example---reference

    In this post, we want to talk about JDBC Transactions and how we can manage the operations in a data ...

  6. Android开发之UI的编程方式创建

    我们知道,android中一个activity对应一个xml的UI配置文件,除了用xml文件配置的方式创建用户界面外,还可以使用代码编程的方式来创建一个用户界面.如果用户界面需要在运行过程中动态生成的 ...

  7. Windows Server 2008 R2中关闭“IE增强的安全配置”

    当在Windows Sever 2008 R2中运动IE8的时候会发现默认情况下IE启用了增强的安全配置,为了方便而且是在内网的情况下我们可以关闭IE8的增强安全配置,操作很简单如下步骤. 一,以本机 ...

  8. CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\d29b5393\123c3a1c\App_Code.odl3w4o6.dll”--“拒绝访问。 ”

    IIS部署网站或者Webservice时,出现以下问题: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Tempor ...

  9. Access的转义字符

    Access中数据库转义字符规则: 插入.更新.=匹配 数据时,文本类型如用''括起来,中间可以有 ",*,%,[,],/,/,?,(,),{,}的任意组合,如要插入一个',需写''并在整个 ...

  10. PhpStorm 注册码

    JetBrains PhpStorm key PhpStorm注册码 User Name :  EMBRACE  License Key : License Key : ===== LICENSE B ...