【Swift 3.1】02 - 基本运算符 (Basic Operators)

基本运算符 (Basic Operators)

自从苹果2014年发布Swift,到现在已经两年多了,而Swift也来到了3.1版本。去年利用工作之余,共花了两个多月的时间把官方的Swift编程指南看完。现在整理一下笔记,回顾一下以前的知识。有需要的同学可以去看官方文档>>。


术语 (Terminology)

运算符有一元、二元和三元:

  • 一元运算符只操作一个操作数(例如-a)。一元运算符写在操作数的前面或者后面,例如!bc!,并且运算符和操作数不能有空格。
  • 二元运算符操作两个操作数(例如2 + 3)。
  • 三元运算符操作三个操作数。像C语言一样,Swift只有一个三元运算符,a ? b : c

赋值运算符 (Assignment Operator)

赋值运算符用来初始化变量的值,或者更新变量的值

let b = 10
var a = 5
a = b
// a现在等于10

如果赋值运算符右边是一个有多个元素的多元组,多元组的元素可以一次性分解成多个常量或者变量:

let (x, y) = (1, 2)
// x等于1,y等于2

不同于C和OC,Swift中的赋值运算符本身不返回任何值。下面这个语句是非法的:

if x = y {
    // 这是非法的,因为x=y不返回任何值
}

算术运算符 (Arithmetic Operators)

Swift支持下面这四个标准的算术运算符:

  • 加 (+)
  • 减 (-)
  • 乘 (*)
  • 除 (/)
1 + 2       // 等于 3
5 - 3       // 等于 2
2 * 3       // 等于 6
10.0 / 2.5  // 等于 4.0

另外,+可以用来拼接String字符串:

"hello, " + "world"  // 等于 "hello, world"
求余运算符 (Remainder Operator)
9 % 4    // 等于 1

为了得出a % b的结果,%这个求余运算符计算下面的等式,并返回remainder

a = (b * some multiplier(另外一个乘数)) + 余数

some multiplierab的最大公约数。

上面的计算方法同样适用于负数:

-9 % 4 // 等于 -1

-94代入那个公式:

-9 = (4 * -2) + -1

所以返回-1

其实b前面的符号可以忽略,也就意味着a % ba % -b的返回值是相等的。

一元减号运算符 (Unary Minus Operator)
let three = 3
let minusThree = -3         // minusThree等于-3
let plusThree = -minusThree // plusThree等于3
一元加号运算符 (Unary Plus Operator)
let minusSix = -6
let alsoMinusSix = +minusSix // alsoMinusSix等于6

一元加号运算符不会改变操作数的值。但是为了保持对称,在代码中负数使用一元加号运算符,正数也加上一元加号运算符。

复合赋值运算符 (Compound Assignment Operators)

var a = 1
a += 2
// a 等于 3

a += 2其实是a = a + 2的简写。

注意:复合赋值运算符不会返回任何值,例如:我们不能这样写:let b = a += 2

比较运算符 (Comparison Operators)

Swift支持全部C语言的标准运算符:

  • 等于 (a == b)
  • 不等于 (a != b)
  • 大于 (a > b)
  • 小于 (a < b)
  • 大于或等于 (a >= b)
  • 小于或等于 (a <= b)

注意:Swift还额外提供了恒等运算符 (identity operator) (===!==),用来判断两个对象是否引用同一个实例。

所有的比较运算符都会返回一个Bool值:

1 == 1   // true 因为 1 等于 1
2 != 1   // true 因为 2 不等于 1
2 > 1    // true 因为 2 大于 1
1 < 2    // true 因为 1 小于 2
1 >= 1   // true 因为 1 大于或等于 1
2 <= 1   // false 因为 2 不是小于或等于 1

比较运算符通常用于条件语句,例如if语句:

let name = "world"
if name == "world" {
    print("hello, world")
} else {
    print("I'm sorry \(name), but I don't recognize you")
}
// Prints "hello, world", because name is indeed equal to "world".

还可以用来比较多元组,只要多元组的元素个数相同,并且每个元素都是可比较的。例如,IntString都是可以比较的,也就意味着多元组(Int, String)也是可以比较的。相反,Bool是不能比较的,所以元素中含有布尔值的多元组是不能比较的。

多元组在比较的时候,是从左到右一个一个比较,直到发现两个参与比较的值不相等,那么这两个不相等的元素的比较结果就作为两个多元组的比较结果。如果每个元素都各自相等,那么这个多元组就相等:

(1, "zebra") < (2, "apple")   // true 因为 1 is less than 2; "zebra" 和 "apple" 不用在比较
(3, "apple") < (3, "bird")    // true 因为 3 等于 3, 并且 "apple" 小于 "bird"
(4, "dog") == (4, "dog")      // true 因为 4 等于 4, 并且 "dog" 等于 "dog"

在上面的例子中,按照从左到右一个个比较的规则,因为1小于2,所以(1, "zebra")小于(2, "apple"),因为已经发现了两个不相等的元素,后面的元素将不再比较,尽管zebra大于apple。然而,当发现两个元素相等时,将会继续往下比较。

注意:Swift标准库只支持小于7个元素的多元组进行比较。如果多元组的元素大于或等于7个,我们必须自己实现比较运算符。

三元运算符 (Ternary Conditional Operator)

三元运算符是有三部分的比较特别的运算符,格式:question ? answer1: answer2。是下面这个代码的简写:

if question {
    answer1
}
else {
    answer2
}

例如下面这个例子:

let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// rowHeight 等于 90

我们要避免使用三元运算符把多个判断条件组合在一起,因为这会造成代码很难读懂。

空合并运算符 (Nil-Coalescing Opeartor)

使用空合并运算符(a ?? b)来解包一个可选类型变量,如果a有值,返回a!,如果为nil,返回默认值ba必须是一个可选类型,b的类型必须a包含的值类型相同。

空合并运算符其实是下面这个代码的简写:

a != nil ? a! : b

下面举个例子:

let defaultColor = "red"
var userDefinedColorName: String? // 默认是nil

var colorNameToUse = userDefinedColorName ?? defaultColor
// userDefinedColorName 为 nil,所以 colorNameToUse被设置为默认值 "red"

范围运算符 (Range Operators)

闭合范围运算符 (Closed Range Operator)

闭合范围运算符(a...b)定义了一个从ab的范围,并且包括aba的值不能大于b

当你想使用一个范围的每一个值时,使用闭合运算符非常有用。例如:

for index in 1...5 {
    print("\(index) 乘以 5 等于 \(index * 5)")
}
// 1 乘以 5 等于 5
// 2 乘以 5 等于 10
// 3 乘以 5 等于 15
// 4 乘以 5 等于 20
// 5 乘以 5 等于 25
半闭合运算符 (Half-Open Range Operator)

半闭合运算符(a..)定义了一个从ab的范围,但是不包括ba的值不能大于b。如果a等于b,那么这个范围就是空的。

在使用下标以0开始的的列表,例如数组,但是不包含数组的长度,使用半闭合运算符非常合适:

let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..

逻辑运算符 (Logical Operators)

Swift支持这三个标准的逻辑运算符:

  • 逻辑非 (!a)
  • 逻辑与 (a && b)
  • 逻辑或 (a || b)
逻辑非运算符 (Logical NOT Operator)

逻辑非让一个布尔值取反,true变为falsefalse变为true

let allowedEntry = false
if !allowedEntry {
    print("拒绝访问")
}
// Prints "拒绝访问"
逻辑与运算符 (Logical AND Operator)

逻辑与运算符(a && b)两边的逻辑语句都为true时,整个语句才是true。如果有其中一个为false,整个语句就为false。实际上,只要第一个语句是false,第二个语句就不会在计算了,因为第二个语句无论是true还是false都不可能把最终的结果改为true

let enteredDoorCode = true
let passedRetinaScan = false
if enteredDoorCode && passedRetinaScan {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "ACCESS DENIED"
逻辑或运算符 (Logical OR Operator)

逻辑或运算符两边的逻辑语句,只要有一个是true,那整个语句就是true。如果第一个语句是true,第二个就不会再计算。

let hasDoorKey = false
let knowsOverridePassword = true
if hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "Welcome!"
组合逻辑运算符 (Combining Logical Operators)
if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "Welcome!"

在这个例子中,使用多个&&||运算符来创建一个更长的复合语句。但是&&||运算符还是仅仅操作两个逻辑语句。上面的代码可以这么读:如果我们输入了正确的门密码并且通过了视网膜扫描,或者有门钥匙,或者我们知道紧急覆盖密码,那么就允许进入。

明确的括号 (Explicit Parentheses)

在恰当的位置加上括号,增强代码的易读性:

if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "Welcome!"

第二部分完。下个部分:【Swift 3.1】03 - 字符串和字符 (Strings and Characters)


如果有错误的地方,欢迎指正!谢谢!

你可能感兴趣的:(【Swift 3.1】02 - 基本运算符 (Basic Operators))