Swift语言官方文档翻译(4)-Basic Operators

Basic Operators


操作符是一种用于检查、操作、组合值的特殊的符号或短语。比如将两个值相加(let i = 1 + 2)的加号(+)。更复杂的比如逻辑与(&&)、自增(++i:表示给i加上一个1后返回)。

Swift支持大多数标准C的操作符,而且为了消除错误增加了一些功能。为了与运算符(==)区分开来,赋值操作符(=)不返回任何值。算术运算符(+,-,*,/,% 等)检测和避免值的溢出,在处理数字时,以免出现比存储类型允许的值范围大或小这些意想不到的结果。你可以使用在Overflow Operators描述的Swift溢出操作符来进行溢出值的展现。

与C不同的是,Swift在浮点数的计算中可以使用余数(%)。Swift提供了2种域操作符(a..<b和a...b)代表一系列值,而C中没有这种操作符。

这一节中描述了Swift常用的操作符。而Advanced Operators一文中描述的是高级操作符,并描述了如何定义您自己的自定义操作符和如何继承自己的自定义类型的标准操作符。


术语


操作符有一元、二元、三元:

  • 一元操作符操作单个目标(比如-a).一元前缀操作符紧贴在他们的目标前(例如!b).一元后缀操作符紧跟在他们的目标后(例如i++)
  • 二元操作符操作目录为2个。因为它们出现在目标中间所以称为中缀
  • 三元操作符操作目标为3个。和C一样,Swift只有一个3元操作符:三元条件运算符(a?b:c)

操作符影响的值叫操作数,在表达式1+2中,加号(+)是一个二元操作符,它有2个操作数:1和2.


赋值运算


赋值运算符(a=b)表示用b的值初始化或更改a的值。


    let b = 10
    var a = 5
    a = b
    // a is now equal to 10


如果赋值运算符的右边是一个含有多个值的元组对象,它的元素可以分解成多个变量或者常量。


    let (x, y) = (1, 2)
    // x is equal to 1, and y is equal to 2


与C和OC中的赋值元素符不同之处在于,Swift中的赋值运算符自身是不返回值的。下面的语句是无效的:


    if x = y {
    // this is not valid, because x = y does not return a value
    }


这种特性避免了赋值运算符(=)被当成等于运算符(==)的错误。因为if x=y是无效的,所以Swift有助于减少代码中出现这种错误。


算术运算符


Swift为所有数字运算提供了4中算术运算符:加(+)减(-)乘(*)除(/).


    1 + 2 // equals 3
    5 - 3 // equals 2
    2 * 3 // equals 6
    10.0 / 2.5 // equals 4.0


与C和OC不同的是,Swift中的算术运算符默认情况下不允许值溢出。但是你可以选择让其可以溢出(a&+b),具体操作见 Overflow Operators一文。

加号(+)可用于字符串的连接:


    "hello, " + "world" // equals "hello, world"


两个字符的值,一个字符和一个字符串的值,可以通过加号形成一个新的string值。


Swift语言官方文档翻译(4)-Basic Operators_第1张图片


其他详情查看Concatenating Strings and Characters.一文。


取余操作符


取余操作符(a%b)计算出a可以容纳多少个b,返回剩下的余数。


注意
取余运算符在其他语言中称为模数运算子。严格来说,Swift中的取余运算符在负数操作上要比模数运算子更有意义。

下面的图显示了取余操作符是如何工作的,为了计算9%4,你首先计算9中包含了多少个4.



很显然,9中含有2个4.然后剩下1。在Swift中,可以写成:


    9 % 4 // equals 1


为了确定a%b的答案,取余运算符(%)下面的方程式返回reminder作为它的结果输出。


 a = (b × some multiplier) + remainder 

some multiplier的值为a所能包含b的个数的最大值。


将9和4放入上面的方程式中


 9 = (4 × 2) + 1 


当a的值是负数时,取余运算符同样适用。


-9 % 4 // equals -1

将-9和4放入方程式中


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

得到余数为-1.


标志符b是忽略a的符号的,所以a%b和a%-b的值是一样的。


浮点取余计算


与C和OC不同的是,在Swift中取余计算同样适用于浮点数。


    8 % 2.5 // equals 0.5


该例中,8包含3个2.5.余下一个0.5。所以上述表达式返回一个double类型的数0.5.


Swift语言官方文档翻译(4)-Basic Operators_第2张图片


自增自减运算


和C一样,Swift提供自增(++)自减(--)运算符,代表在一个数上进行加1和减1操作。任何整型和浮点型的变量都可以使用。


    var i = 0
    ++i // i now equals 1



每一次调用++i,i的值都会加1.事实上,++i就是i=i+1的意思。类似的--i就是i=i-1的意思。++和--标识符既可以作为前缀也可以作为后缀。++i和i++都是加1的操作。同理,--i和i--都是减1的操作。


注意操作符对i的修改和返回的值。如果你只想对存储在i中的值减1或加1,你可以不用在意返回值。如果你想使用返回值,要注意++和--的前缀和后缀的区别。

  • 如果操作符在变量前,那么变量会先增加1或者减少1后再返回.
  • 如果操作符在变量后,那么变量会先返回然后再增加1或减少1。


如下面例子:


    var a = 0
    let b = ++a
    // a and b are now both equal to 1
    let c = a++
    // a is now equal to 2, but c has been set to the pre-increment value of 1


上面的例子中,let b=++a会先加1在返回。let c=a++中a会先返回再加1.所以c会得到a之前的值1.然后a变为2.


如果你没有特殊的需求,推荐在任何情况下都使用++或--标识符。因为他们在修改变量后返回值方面有典型的预期表现。


一元减操作符


有符号的数字可以通过在前面添加减号(-)来转换值,称为一元减操作符。


    let three = 3
    let minusThree = -three // minusThree equals -3
    let plusThree = -minusThree // plusThree equals 3, or "minus minus three"


一元减操作符(-)是直接放在变量前的,之间没有空格。


一元加操作符


有符号的数字可以通过在前面添加加号(+)来转换值,称为一元加操作符。


    let minusSix = -6
    let alsoMinusSix = +minusSix // alsoMinusSix equals -6


虽然一元加操作符实际上没做任何操作,当你在编写代码时,遇到正数的情况下使用一元加操作符可以使代码变的对称。


复合赋值运算符


和C一样,Swift也提供将赋值运算符(=)与其他操作符组合在一起,称为复合赋值运算符。下面的例子中的复合赋值运算符为加等(+=)运算符。


    var a = 1
    a += 2
    // a is now equal to 3


表达式a+=2实际上是a=a+2。事实上加号和等号就是组合到一个操作符进行加和赋值的运算。


注意
复合运算符没有返回值,你不能写成let c = a+=2.这和上面的提到的自增和自减效果是不一样的

如果你想了解更多的复合运算操作符可以参见 Expressions. 一文。


比较运算符

Swift支持所有C的比较运算符。


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


注意
Swift也提供2中特性的比较操作符(===和!==),这是用来比较继承同一个对象的子对象是否是同一个实例。想了解更多,请看<span class="x-name"><a target=_blank href="https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-XID_95" data-id="//apple_ref/doc/uid/TP40014097-CH13-XID_95">Classes and Structures</a></span>一文。


每一个比较操作符都会返回一个Bool类型的值来表示表达式是否为真。


    1 == 1 // true, because 1 is equal to 1
    2 != 1 // true, because 2 is not equal to 1
    2 > 1 // true, because 2 is greater than 1
    1 < 2 // true, because 1 is less than 2
    1 >= 1 // true, because 1 is greater than or equal to 1
    2 <= 1 // false, because 2 is not less than or equal to 1


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


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


想看更多关于if语句的信息,参考 Control Flow一文。


三元条件运算符


三元条件运算符是含有3部分的特殊运算符。其形式为question?answer1:answer2.它会根据questions得出的Bool值来选择后面2个表达式之一来进行计算。如果question的值为true那么就会选择answer1来计算,反之选择answer2来计算。

三元田间运算符类似下面的形式:


    if question {
    answer1
    } else {
    answer2
    }


举例说明:现在需要计算一个表中行的高度。要求是如果存在行标题,行的高度要比内容高度高50个单位。如果不存在行标题那么行的高度就比内容高20个单位。


    let contentHeight = 40
    let hasHeader = true
    let rowHeight = contentHeight + (hasHeader ? 50 : 20)
    // rowHeight is equal to 90


上面的代码就是下面的代码的简写形式:


    let contentHeight = 40
    let hasHeader = true
    var rowHeight = contentHeight
    if hasHeader {
    rowHeight = rowHeight + 50
    } else {
    rowHeight = rowHeight + 20
    }
    // rowHeight is equal to 90


上面运用三元条件运算符的例子表示 rowHeight值初始化只需一行代码就可以搞定。比第二个例子更简洁。而且rowHeight也不需要是变量,因为它的值在if语句里不会改变。

三元运算符对于2个表达式的运算是很高效的,但是要小心使用。如果过度使用会使代码变得晦涩难懂。避免组合使用多种三元运算符。


范围运算符


Swift提供2种范围运算符,表示值的范围。


封闭范围运算符


封闭运算符(a...b)代表了a到b的范围,而且还包括a和b。当你想包括一系列数中的所有数,例如用for 。。in表达式时,使用封闭运算符是更好的。


    for index in 1...5 {
    println("\(index) times 5 is \(index * 5)")
    }
    // 1 times 5 is 5
    // 2 times 5 is 10
    // 3 times 5 is 15
    // 4 times 5 is 20
    // 5 times 5 is 25


想了解更多关于for..in循环的,参考 Control Flow一文。


半封闭范围运算符


半封闭运算符(a..<b)表示a到b范围内的数,但是不包括b。叫它半封闭的原因是它包括第一个数但是不包含最后一个数。

当你用在数组这种以0为起始值的列表中,半封闭是很有用的。遍历数组(不包括最后一个)是很方便的。


et names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
println("Person \(i + 1) is called \(names[i])")
}
// Person 1 is called Anna
// Person 2 is called Alex
// Person 3 is called Brian
// Person 4 is called Jack

上面的数组包含4个元素,但是因为它是半封闭的0..<count只记数到3(数组中的最后一个数)。更多详情,参考 Arrays一文。

但是实际代码中发现a..<b这种方式并不正确,而a..b有半闭的效果。


<span style="color:#FF0000;">let a = 4
for i in 0..a {
   println(i)
}

let b = 5
for i in 0...b {
    println(i)
}</span>


且a..b和a...b中间不要有空格,不然也会有问题


逻辑运算符


逻辑运算修改和组合逻辑值true和false.和C中的逻辑元素一样,Swift也提供3中逻辑运算符。


  • 逻辑非(!a)
  • 逻辑与(a&&b)
  • 逻辑或(a||b)


逻辑非


逻辑非(!a)倒置布尔值,true的值变为false,false的值变为true.逻辑非是个前缀操作符,紧贴在布尔值的前面,中间不能有空格,可以读作not a。看下面的例子。


    let allowedEntry = false
    if !allowedEntry {
    println("ACCESS DENIED")
    }
    // prints "ACCESS DENIED"



表达式if !allowedEntry意思是if not allowed entry.如果allowedEntry的值是false,括号里的代码才能执行。在上面的例子中,认真挑选布尔值的常量和变量会使代码变得易读和简洁,避免了双重否定和混乱的语句出现。


逻辑与


逻辑与运算符(&&)比如符号两边的表达式都必须是true,运算结果才是true.如果有一个值是false,那么表达式就是false.如果第一个值为false,那么就不会计算第二个值就直接返回false,因为表达式的值肯定为false,无需再继续第二个表达式的值。这种方式称为短路计算。

下面的例子会考虑2个布尔值,而且2个布尔值都是true时才会继续处理。


    let enteredDoorCode = true
    let passedRetinaScan = false
    if enteredDoorCode && passedRetinaScan {
    println("Welcome!")
    } else {
    println("ACCESS DENIED")
    }
    // prints "ACCESS DENIED"


逻辑或


逻辑或运算符是把操作符放在两个相邻字节中间。你可以使用它创建逻辑表达式,这种表达式中的任何一个值为true,表达式就会返回true.和上面的逻辑与一样,逻辑或也是采用短路的形式处理表达式的。如果表达式坐标的值为true,就不会再执行右边的表达式。因为无论右边的值为什么,表达式的值都为true.

下面的例子中,第一个Bool值为false,但是第二个Bool值为true,那么表达式的值就为true.


    let hasDoorKey = false
    let knowsOverridePassword = true
    if hasDoorKey || knowsOverridePassword {
    println("Welcome!")
    } else {
    println("ACCESS DENIED")
    }
    // prints "Welcome!"


逻辑运算符的组合


你可以通过组合多个逻辑运算符形成一个复合的表达式。


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


上面的例子用逻辑与(&&)和逻辑或(||)组合形成了一个复合表达式。但是逻辑与和逻辑或只处理符号两边的表达式,所以上面的复合表达式可以理解为3个表达式的合体。

上面的表达式可以理解为:


如果我进入大门,通过视网膜扫描或者有门钥匙或者知道门的密码,我就可以进入房间。基于enteredDoorCode、passedRetinaScan和hasDoorKey的值,第一次或的运算结果是false.但是你知道密码,整个表达式的结果也为true.


明确的括号


有时在你不是非常需要括号的时候,我们推荐你使用括号在规范你的代码是很有必要的。在上面的事例代码中,在第一个部分打上括号是很有利于代码的阅读的。


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


括号可以使得开头的2个表达式从整个表达式中独立出来,我们这时只考虑这2个值。表达式的输出结果也不会因为加了括号而发生变化,但是表达式变得易读。易读性优于简洁性。使用括号会使你的意图更清晰。











你可能感兴趣的:(swift)