Swift心得笔记之运算符

空值合并运算符和区间运算符

今天主要看的内容是 Swift 中的基本运算符。记录一下。

Nil Coalescing Operator

a ?? b 中的 ?? 就是是空值合并运算符,会对 a 进行判断,如果不为 nil 则解包,否则就返回 b 。

var a: String? = "a"
var b: String? = "b"
var c = a ?? b   // "a"
a = nil
c = a ?? b     // "b"
b = nil
c = a ?? b ?? "c"  // "c"

使用的时候有以下两点要求:

a 必须是 optional 的
b 必须和 a 类型一致
也就是说,a 一定要有被备胎的可能,b 一定要有做备胎的资格。

其实也就是对三目运算符的简写:

复制代码 代码如下:

a != nil ? a! : b 或者 a == nil ? b : a!

当然你也可以通过自定义运算符来实现:

infix operator ||| {}

func |||<T> (left: T?, right: T) -> T {
  if let l = left {
    return l
  }
  return right
}

var a:String?
var b = "b"
var c = a ||| b

C# 中也有个 ?? ,感兴趣的可以去了解一下。

Range Operator

区间运算符分为闭区间 (...) 和左闭右开区间 (..<) 两种,前者是算头算尾,后者是算头不算尾。

可以应用在 switch 中:

switch aNumber
{
case 0...5:
  println("This number is between 0 and 5")
case 6...10:
  println("This number is between 6 and 10")
default:
  println("This number is not between 0 and 10")
}

区间运算符其实返回的是一个 Range<T> 对象,是一个连续无关联序列索引的集合。

话说以前左闭右开是 .. ,这样和 Ruby 的就刚好完全相反了。。。

不过有人就是想用 .. ,那么可以这样自己写一个:

infix operator .. { associativity none precedence 135}

func .. (lhs: Int, rhs: Int) -> Range<Int> {
  return lhs..<rhs
}

for i in 0..10 {
  println("index \(i)")
}

你也可以用 generate() 来遍历:

var range = 1...4
var generator = range.generate()  // {startIndex 1, endIndex 5}
generator.next() // 1
generator.next() // 2
generator.next() // 3
generator.next() // 4
generator.next() // nil

.generate() 返回一个 RangeGenerator<T> 的结构体,可以用来遍历 Range<T> 中的值。

以前还有个 (5...1).by(-1) 的用法,不过现在好像没用了。

区间运算符返回的是一个 ClosedInterval 或者 HalfOpenInterval 的东西,类型只要是 Comparable 就可以了。所以我们也可以把 String 放到 ... 里。

比如猫神的 Swifter Tips 中有一章的代码如下,通过 String 的 ClosedInterval 来输出字符串中的小写字母:

let test = "Hello"
let interval = "a"..."z"

for c in test {
  if interval.contains(String(c)) {
    println("\(c)")
  }
}

SubString

Ruby 中用点点点来获取 SubString 的方法很方便:

2.1.3 :001 > a="abc"
 => "abc"
2.1.3 :002 > a[0]
 => "a"
2.1.3 :003 > a[0..1]
 => "ab"

而 Swift 中的 ClosedInterval 是没有 subscript 的。但是任性的我们就是要用 [1...3] 这种方法怎么办呢?
自己动手丰衣足食,写个 extension 吧,只需要加个 subscript 就可以了,然后下标的类型是 Range<Int> 就可以了:

extension String {
  subscript (r: Range<Int>) -> String {
    get {
      let startIndex = advance(self.startIndex, r.startIndex)
      let endIndex = advance(startIndex, r.endIndex - r.startIndex)

      return self[Range(start: startIndex, end: endIndex)]
    }
  }
}

var s = "Hello, playground"

println(s[0...5]) // ==> "Hello,"
println(s[0..<5]) // ==> "Hello"

如果要搜索目标字符串之后再截取 substring 可以这样:

let name = "Joris Kluivers"

let start = name.startIndex
let end = find(name, " ")

if (end != nil) {
  let firstName = name[start..<end!]
} else {
  // no space found
}

以上所述就是本文的全部内容了,希望大家能够喜欢。

时间: 2015-04-19

Swift教程之基本运算符详解

运算符是一种特定的符号或表达式,用来检验.修改或合并变量.例如,用求和运算符+可以对两个数字进行求和(如let i = 1 + 2):稍微复杂一点的例子有逻辑与操作符&& (如if enteredDoorCode && passedRetinaScan) ,自增长运算符 ++i (这是i=i+1的简写方式) Swift支持C标准库中的大多数运算符并提升了各自的兼容性,从而可以排除常见的编码错误.赋值操作符 (=)不会返回一个值,这样可以防止你因粗心将赋值运算符 (=)写成

Swift教程之基础数据类型详解

基础类型 虽然Swift是一个为开发iOS和OS X app设计的全新编程语言,但是Swift的很多特性还是跟C和Objective-C相似. Swift也提供了与C和Objective-C类似的基础数据类型,包括整形Int.浮点数Double和Float.布尔类型Bool以及字符串类型String.Swift还提供了两种更强大的基本集合数据类型,Array和Dictionary,更详细的内容可以参考:Collection Types. 跟C语言一样,Swift使用特定的名称来定义和使用变量.同

swift中自定义正则表达式运算符=~详解

什么是正则表达式? 正则表达式,又称正规表示法.常规表示法(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式使用单个字符串来描述.匹配一系列符合某个句法规则的字符串.在很多文本编辑器里,正则表达式通常被用来检索.替换那些符合某个模式的文本. swift 至今并没有在语言层面上支持正则表达式,可能在开发app时正则表达式使用的场景并不多. 封装 在 Cocoa 中我们可以使用 NSRegularExpression 来做

Swift教程之枚举类型详解

枚举定义了一个常用的具有相关性的一组数据,并在你的代码中以一个安全的方式使用它们. 如果你熟悉C语言,你就会知道,C语言中的枚举指定相关名称为一组整数值.在Swift中枚举更为灵活,不必为枚举的每个成员提供一个值.如果一个值(被称为"原始"的值)被提供给每个枚举成员,则该值可以是一个字符串,一个字符,或者任何整数或浮点类型的值. 另外,枚举成员可以指定任何类型,每个成员都可以存储的不同的相关值,就像其他语言中使用集合或变体.你还可以定义一组通用的相关成员为一个枚举,每一种都有不同的一组

Swift教程之集合类型详解

Swift 提供两种集合类型来存储集合,数组和字典.数组是一个同类型的序列化列表集合.字典是一个能够使用类似于键的唯一标识符来获取值的非序列化集合. 在Swift中,数组和字典的键和值都必须明确它的类型.这意味这数组和字典不会插入一个错误的类型的值,以致于出错.这也意味着当你在数组和字典中取回数值的时候能够确定它的类型. Swift 使用确定的集合类型可以保证代码工作是不会出错,和让你在开发阶段就能更早的捕获错误. note: Swift的数组 储存不同的类型会展示出不同的行为,例如变量,常量或

Swift教程之类与结构详解

类与结构是编程人员在代码中会经常用到的代码块.在类与结构中可以像定义常量,变量和函数一样,定义相关的属性和方法以此来实现各种功能. 和其它的编程语言不太相同的是,Swift不需要单独创建接口或者实现文件来使用类或者结构.Swift中的类或者结构可以在单文件中直接定义,一旦定义完成后,就能够被直接其它代码使用. 注意:一个类的实例一般被视作一个对象,但是在Swift中,类与结构更像是一个函数方法,在后续的章节中更多地是讲述类和结构的功能性. 1.类和结构的异同 类和结构有一些相似的地方,它们都可以

Swift教程之类的析构详解

在一个类的实例被释放之前,析构函数会被调用.用关键字deinit来定义析构函数,类似于初始化函数用init来定义.析构函数只适用于class类型. 1.析构过程原理 Swift 会自动释放不再需要的实例以释放资源.如自动引用计数那一章描述,Swift 通过自动引用计数(ARC)处理实例的内存管理.通常当你的实例被释放时不需要手动地去清理.但是,当使用自己的资源时,你可能需要进行一些额外的清理.例如,如果创建了一个自定义的类来打开一个文件,并写入一些数据,你可能需要在类实例被释放之前关闭该文件.

kotlin 官方学习教程之基础语法详解

kotlin 官方学习教程之基础语法详解 Google 在今天的举行了 I/O 大会,大会主要主要展示内有容 Android O(Android 8.0)系统.Google Assistant 语音助手.Google 智能音箱.人工智能.机器学习.虚拟现实等.作为一个 Android 开发者,我关心的当然是 Android O(Android 8.0)系统了,那么关于 Android O 系统的一个重要消息是全面支持 Kotlin 编程语言,使得 Kotlin 成为了 Android 开发的官方

基于C++ bitset常用函数及运算符(详解)

C++ bitset--高端压位卡常题必备STL ------------------------------------------------------------ 以下内容翻译自cplusplus.com,极大地锻炼了我的英语能力. bitset存储二进制数位. bitset就像一个bool类型的数组一样,但是有空间优化--bitset中的一个元素一般只占1 bit,相当于一个char元素所占空间的八分之一. bitset中的每个元素都能单独被访问,例如对于一个叫做foo的bitset,

IOS 开发之swift中手势的实例详解

IOS 开发之swift中手势的实例详解 手势操作主要包括如下几类 手势 属性 说明 点击 UITapGestureRecognizer numberOfTapsRequired:点击的次数:numberOfTouchesRequired:点击时有手指数量 设置属性 numberOfTapsRequired 可以实现单击,或双击的效果 滑动 UISwipeGestureRecognizer direction:滑动方向 direction 滑动方向分为上Up.下Down.左Left.右Right