Basic Operators (基本运算符)

Anoperatoris a special symbol or phrase that you use to check, change, or combine values. For example, the addition operator (+) adds two numbers, as inlet i = 1 + 2, and the logical AND operator (&&) combines two Boolean values, as inif enteredDoorCode && passedRetinaScan.

运算符是检查、改变、合并值的特殊符号或短语。例如,加号(+)将两个数相加(如let i = 1 + 2)。更复杂的运算例子包括逻辑与运算符&&(如if enteredDoorCode && passedRetinaScan)。

Swift supports most standard C operators and improves several capabilities to eliminate common coding errors. The assignment operator (=) does not return a value, to prevent it from being mistakenly used when the equal to operator (==) is intended. Arithmetic operators (+,-,*,/,%and so forth) detect and disallow value overflow, to avoid unexpected results when working with numbers that become larger or smaller than the allowed value range of the type that stores them. You can opt in to value overflow behavior by using Swift’s overflow operators, as described inOverflow Operators.

Swift 支撑大部分标准 C 语言的运算符,且改进许多特性来减少常规编码错误。如:赋值符(=)不返回值,以防止把想要判断相等运算符(==)的地方写成赋值符导致的错误。算术运算符(+,-,*,/,%等)会检测并不允许值溢出,以此来避免保存变量时由于变量大于或小于其类型所能承载的范围时导致的异常结果。当然允许你使用 Swift 的溢出运算符来实现溢出。详情参见溢出运算符。

Swift also provides two range operators (a..<b and a...b) not found in C, as a shortcut for expressing a range of values.

Swift 还提供了 C 语言没有的表达两数之间的值的区间运算符(a..

This chapter describes the common operators in Swift.Advanced Operatorscovers Swift’s advanced operators, and describes how to define your own custom operators and implement the standard operators for your own custom types

本章节只描述了 Swift 中的基本运算符,高级运算符这章会包含 Swift 中的高级运算符,及如何自定义运算符,及如何进行自定义类型的运算符重载。

Terminology (术语)

Operators are unary, binary, or ternary:

运算符分为一元、二元和三元运算符:

1. Unaryoperators operate on a single target (such as-a). Unaryprefixoperators appear immediately before their target (such as!b), and unarypostfixoperators appear immediately after their target (such asc!).

一元运算符对单一操作对象操作(如-a)。一元运算符分前置运算符和后置运算符,前置运算符需紧跟在操作对象之前(如!b),后置运算符需紧跟在操作对象之后(如c!)。

2. Binaryoperators operate on two targets (such as2 + 3) and areinfixbecause they appear in between their two targets.

二元运算符操作两个操作对象(如2 + 3),是中置的,因为它们出现在两个操作对象之间。

3. Ternaryoperators operate on three targets. Like C, Swift has only one ternary operator, the ternary conditional operator (a ? b : c).

三元运算符操作三个操作对象,和 C 语言一样,Swift 只有一个三元运算符,就是三目运算符(a ? b : c)。

The values that operators affect areoperands. In the expression1 + 2, the+symbol is a binary operator and its two operands are the values1and2.

受运算符影响的值叫操作数,在表达式1 + 2中,加号+是二元运算符,它的两个操作数是值1和2。

Assignment Operator (赋值去处符)

Theassignment operator(a = b) initializes or updates the value ofawith the value ofb:

赋值运算符(a = b),表示用b的值来初始化或更新a的值:

let b=10

var a=5

a=b

// a is now equal to 10

If the right side of the assignment is a tuple with multiple values, its elements can be decomposed into multiple constants or variables at once:

如果赋值的右边是一个多元组,它的元素可以马上被分解成多个常量或变量:

let(x ,y) = (1,2)

// x is equal to 1, and y is equal to 2

Unlike the assignment operator in C and Objective-C, the assignment operator in Swift does not itself return a value. The following statement is not valid:

与 C 语言和 Objective-C 不同,Swift 的赋值操作并不返回任何值。所以以下代码是错误的:

if x=y {

??? // This is not valid, because x = y does not return a value.

}

This feature prevents the assignment operator (=) from being used by accident when the equal to operator (==) is actually intended. By makingif x = yinvalid, Swift helps you to avoid these kinds of errors in your code.

这个特性使你无法把(==)错写成(=),由于if x = y是错误代码,Swift 能帮你避免此类错误发生。

Arithmetic Operators (算术运算符)

Swift supports the four standardarithmetic operatorsfor all number types:

Swift 中所有数值类型都支撑了基本的四则算术运算符

Addition (+)? //加

Subtraction (-)? //减

Multiplication (*)? //乘

Division (/)? //除

1+2? // equals 3

5-3? // equals 2

2*3? // equals 6

10.0/2.5? // equals 4.0

Unlike the arithmetic operators in C and Objective-C, the Swift arithmetic operators do not allow values to overflow by default. You can opt in to value overflow behavior by using Swift’s overflow operators (such asa &+ b). SeeOverflow Operators.

与 C 语言和 Objective-C 不同的是,Swift 默认情况下不允许在数值运算中出现溢出情况。但是你可以使用 Swift 的溢出运算符来实现溢出运算(如a &+ b)。详情参见溢出运算符。

The addition operator is also supported forStringconcatenation:

加法运算符也可用于String的拼接:

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

Remainder Operator (求余运算符)

Theremainder operator(a % b) works out how many multiples ofbwill fit insideaand returns the value that is left over (known as theremainder).

求余运算符(a % b)是计算b的多少倍刚刚好可以容入a,返回多出来的那部分(余数)。

Note

The remainder operator (%) is also known as amodulo operatorin other languages. However, its behavior in Swift for negative numbers means that it is, strictly speaking, a remainder rather than a modulo operation.

求余运算符(%)在其他语言也叫取模运算符。然而严格说来,大家看该运算符对负数的操作结果,「求余」比「取模」更合适些。

Here’s how the remainder operator works. To calculate9 % 4, you first work out how many4s will fit inside9:

大家来谈谈取余是怎么回事,计算9 % 4,你先计算出4的多少倍会刚好可以容入9中:


You can fit two4s inside9, and the remainder is1(shown in orange).

你可以在9中放入两个4,那余数是 1(用橙色标出)。

In Swift, this would be written as:

在 Swift 中可以表达为:

9%4? // equals 1

To determine the answer fora % b, the%operator calculates the following equation and returnsremainderas its output:

为了得到a % b的结果,%计算了以下等式,并输出余数作为结果:

a= (b x some multiplier) +remainder

// a = (b * 倍数) + 余数

wheresome multiplieris the largest number of multiples ofbthat will fit insidea.

当倍数取最大值的时候,就会刚好可以容入a中。

Inserting 9 and 4 into this equation yields:

把9和4代入等式中,大家得1:

9= (4x2) +1

The same method is applied when calculating the remainder for a negative value ofa:

同样的方法,计算a的负值的余数:

-9%4? // equals -1

Inserting-9and4into the equation yields:

将方程9和4插入到方程中得到::

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

giving a remainder value of-1

余数是-1。

The sign ofbis ignored for negative values ofb. This means thata % banda % -balways give the same answer.

在对负数b求余时,b的符号会被忽略。这意味着a % b和a % -b的结果是相同的。

Unary Minus Operator (一元负号运算符)

The sign of a numeric value can be toggled using a prefixed-, known as theunary minus operator:

数值的正负号可以使用前缀-(即一元负号符)来切换:

let three=3

let minusThree= -three? // minusThree equals -3

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

The unary minus operator (-) is prepended directly before the value it operates on, without any white space.

一元负号符(-)写在操作数之前,中间没有空格。

Unary Plus Operator (一元正号运算符)

Theunary plus operator(+) simply returns the value it operates on, without any change:

一元正号符(+)不做任何改变地返回操作数的值:

let minusSix=-6

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

Although the unary plus operator doesn’t actually do anything, you can use it to provide symmetry in your code for positive numbers when also using the unary minus operator for negative numbers.

虽然一元正号符什么都不会改变,但当你在使用一元负号来表达负数时,你可以使用一元正号来表达正数,如此你的代码会具有对称美。

Compound Assignment Operators

Like C, Swift providescompound assignment operatorsthat combine assignment (=) with another operation. One example is theaddition assignment operator(+=):

如同 C 语言,Swift 也提供把其他运算符和赋值运算(=)组合的组合赋值运算符,组合加运算(+=)是其中一个例子:

var a=1

a+=2

// a is now equal to 3

The expressiona += 2is shorthand fora = a + 2. Effectively, the addition and the assignment are combined into one operator that performs both tasks at the same time.

表达式a += 2是a = a + 2的简写,一个组合加运算就是把加法运算和赋值运算组合成进一个运算符里,同时完成两个运算任务。

Note

The compound assignment operators do not return a value. For example, you cannot writelet b = a += 2.

复合赋值运算没有返回值,let b = a += 2这类代码是错误。这不同于上面提到的自增和自减运算符。

For a complete list of the compound assignment operators provided by the Swift standard library, seeSwift Standard Library Operators Reference.

在Swift 标准库运算符参考章节里有复合运算符的完整列表。

Comparison Operators (比较运算符)

Swift supports all standard Ccomparison operators:

所有标准 C 语言中的比较运算符都可以在 Swift 中使用:

Equal to (a == b)

Not equal to (a != b)

Greater than (a > b)

Less than (a < b)

Greater than or equal to (a >= b)

Less than or equal to (a <= b)

Note

Swift also provides twoidentity operators(===and!==), which you use to test whether two object references both refer to the same object instance. For more information, seeClasses and Structures.

Swift 也提供恒等(===)和不恒等(!==)这两个比较符来判断两个对象是否引用同一个对象实例。更多细节在类与结构。

Each of the comparison operators returns aBoolvalue to indicate whether or not the statement is true:

每个比较运算都返回了一个标识表达式是否成立的布尔值:

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

Comparison operators are often used in conditional statements, such as the if statement:

比较运算多用于条件语句,如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".

For more on theifstatement, seeControl Flow.

关于if语句,请看控制流。

You can also compare tuples that have the same number of values, as long as each of the values in the tuple can be compared. For example, bothIntandStringcan be compared, which means tuples of the type(Int, String)can be compared. In contrast,Boolcan’t be compared, which means tuples that contain a Boolean value can’t be compared.

当元组中的值可以比较时,你也可以使用这些运算符来比较它们的大小。例如,因为Int和String类型的值可以比较,所以类型为(Int, String)的元组也可以被比较。相反,Bool不能被比较,也意味着存有布尔类型的元组不能被比较。

Tuples are compared from left to right, one value at a time, until the comparison finds two values that aren’t equal. Those two values are compared, and the result of that comparison determines the overall result of the tuple comparison. If all the elements are equal, then the tuples themselves are equal. For example:

比较元组大小会按照从左到右、逐值比较的方式,直到发现有两个值不等时停止。如果所有的值都相等,那么这一对元组大家就称它们是相等的。例如:

(1,"zebra") < (2,"apple")? // true because 1 is less than 2; "zebra" and "apple" are not??? compared

(3,"apple") < (3,"bird")? // true because 3 is equal to 3, and "apple" is less than "bird"

(4,"dog") == (4,"dog")? // true because 4 is equal to 4, and "dog" is equal to "dog"

In the example above, you can see the left-to-right comparison behavior on the first line. Because1is less than2,(1, "zebra")is considered less than(2, "apple"), regardless of any other values in the tuples. It doesn’t matter that"zebra"isn’t less than"apple", because the comparison is already determined by the tuples’ first elements. However, when the tuples’ first elements are the same, their second elementsarecompared—this is what happens on the second and third line.

在上面的例子中,你可以看到,在第一行中从左到右的比较行为。因为1小于2,所以(1, "zebra")小于(2, "apple"),不管元组剩下的值如何。所以"zebra"小于"apple"没有任何影响,因为元组的比较已经被第一个元素决定了。不过,当元组的第一个元素相同时候,第二个元素将会用作比较-第二行和第三行代码就发生了这样的比较。

Note

The Swift standard library includes tuple comparison operators for tuples with fewer than seven elements. To compare tuples with seven or more elements, you must implement the comparison operators yourself.

Swift 标准库只能比较七个以内元素的元组比较函数。如果你的元组元素超过七个时,你需要自己实现比较运算符。

Ternary Conditional Operator (三目运算符)

Theternary conditional operatoris a special operator with three parts, which takes the formquestion ? answer1 : answer2. It is a shortcut for evaluating one of two expressions based on whetherquestionis true or false. Ifquestionis true, it evaluatesanswer1and returns its value; otherwise, it evaluatesanswer2and returns its value.

三目运算符的特殊在于它是有三个操作数的运算符,它的形式是问题 ? 答案 1 : 答案 2。它简洁地表达根据问题成立与否作出二选一的操作。如果问题成立,返回答案 1的结果;反之返回答案 2的结果。

The ternary conditional operator is shorthand for the code below:

三目运算符是以下代码的缩写形式:

if question {

??? answer1

} else {

??? answer2

}

Here’s an example, which calculates the height for a table row. The row height should be 50 points taller than the content height if the row has a header, and 20 points taller if the row doesn’t have a header:

这里有个计算表格行高的例子。如果有表头,那行高应比内容高度要高出 50 点;如果没有表头,只需高出 20 点:

let contentHeight=40

let hasHeader=true

let rowHeight=contentHeight+ (hasHeader?50:20)

// rowHeight is equal to 90

The preceding example is shorthand for the code below:

上面的写法比下面的代码更简洁:

let contentHeight=40

let hasHeader=true

let rowHeight:Int

if hasHeader{

??? rowHeight=contentHeight+50

} else {

??? rowHeight=contentHeight+20

}

// rowHeight is equal to 90

The first example’s use of the ternary conditional operator means thatrowHeightcan be set to the correct value on a single line of code, which is more concise than the code used in the second example.

第一段代码例子使用了三目运算,所以一行代码就能让大家得到正确答案。这比第二段代码简洁得多,无需将rowHeight定义成变量,因为它的值无需在if语句中改变。

The ternary conditional operator provides an efficient shorthand for deciding which of two expressions to consider. Use the ternary conditional operator with care, however. Its conciseness can lead to hard-to-read code if overused. Avoid combining multiple instances of the ternary conditional operator into one compound statement.

三目运算提供有效率且便捷的方式来表达二选一的选择。需要注意的事,过度使用三目运算符会使简洁的代码变的难懂。大家应避免在一个组合语句中使用多个三目运算符。

Nil-Coalescing Operator

Thenil-coalescing operator(a ?? b) unwraps an optionalaif it contains a value, or returns a default valuebifaisnil. The expressionais always of an optional type. The expressionbmust match the type that is stored insidea.

空合运算符(a ?? b)将对可选类型a进行空判断,如果a包含一个值就进行解封,否则就返回一个默认值b。表达式a必须是 Optional 类型。默认值b的类型必须要和a存储值的类型保持一致。

The nil-coalescing operator is shorthand for the code below:

空合运算符是对以下代码的简短表达方法:

a != nil ? a! : b

The code above uses the ternary conditional operator and forced unwrapping (a!) to access the value wrapped insideawhenais notnil, and to returnbotherwise. The nil-coalescing operator provides a more elegant way to encapsulate this conditional checking and unwrapping in a concise and readable form.

上述代码使用了三目运算符。当可选类型a的值不为空时,进行强制解封(a!),访问a中的值;反之返回默认值b。无疑空合运算符(??)提供了一种更为优雅的方式去封装条件判断和解封两种行为,显得简洁以及更具可读性。

Note

If the value ofais non-nil, the value ofbis not evaluated. This is known asshort-circuit evaluation.

如果a为非空值(non-nil),那么值b将不会被计算。这也就是所谓的短路求值

The example below uses the nil-coalescing operator to choose between a default color name and an optional user-defined color name:

下文例子采用空合运算符,实现了在默认颜色名和可选自定义颜色名之间抉择:

let defaultColorName="red"

var userDefinedColorName:String?? // defaults to nil

var colorNameToUse=userDefinedColorName ?? defaultColorName

// userDefinedColorName is nil, so colorNameToUse is set to the default of "red"

// userDefinedColorName 的值为空,所以 colorNameToUse 的值为 "red"

TheuserDefinedColorNamevariable is defined as an optionalString, with a default value ofnil. BecauseuserDefinedColorNameis of an optional type, you can use the nil-coalescing operator to consider its value. In the example above, the operator is used to determine an initial value for aStringvariable calledcolorNameToUse. BecauseuserDefinedColorNameisnil, the expressionuserDefinedColorName ?? defaultColorNamereturns the value ofdefaultColorName, or"red".

userDefinedColorName变量被定义为一个可选的String类型,默认值为nil。由于userDefinedColorName是一个可选类型,大家可以使用空合运算符去判断其值。在上一个例子中,通过空合运算符为一个名为colorNameToUse的变量赋予一个字符串类型初始值。由于userDefinedColorName值为空,因此表达式userDefinedColorName ?? defaultColorName返回defaultColorName的值,即red。

If you assign a non-nilvalue touserDefinedColorNameand perform the nil-coalescing operator check again, the value wrapped insideuserDefinedColorNameis used instead of the default:

另一种情况,分配一个非空值(non-nil)给userDefinedColorName,再次实行空合运算,运算结果为封包在userDefaultColorName中的值,而非默认值。

userDefinedColorName="green"

colorNameToUse=userDefinedColorName??defaultColorName

// userDefinedColorName is not nil, so colorNameToUse is set to "green"

Range Operators (区间运算符)

Swift includes tworange operators, which are shortcuts for expressing a range of values.

Swift 提供了两个方便表达一个区间的值的区间运算符

Closed Range Operator (闭区间运算符)

Theclosed range operator(a...b) defines a range that runs fromatob, and includes the valuesaandb. The value ofamust not be greater thanb.

闭区间运算符(a...b)定义一个包含从a到b(包括a和b)的所有值的区间。a的值不能超过b。?闭区间运算符在迭代一个区间的所有值时是非常有用的,如在for-in循环中:

The closed range operator is useful when iterating over a range in which you want all of the values to be used, such as with a for-inloop:

当你想要使用所有的值这样的一个范围(例如for-in循环)进行迭代时,闭区间运算符很有用:

for index in 1...5 {

??? print("\(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 more onfor-inloops, seeControl Flow.

关于for-in,请看控制流。

Half-Open Range Operator (半开区间运算符)

Thehalf-open range operator(a..half-openbecause it contains its first value, but not its final value. As with the closed range operator, the value ofamust not be greater thanb. If the value ofais equal tob, then the resulting range will be empty.

半开区间运算符(a..<b) 定义一个从a到b但不包括b的区间。之所以称为半开区间,是因为该区间包含第一个值而不包括最后的值。

Half-open ranges are particularly useful when you work with zero-based lists such as arrays, where it is useful to count up to (but not including) the length of the list:

半开区间的实用性在于当你使用一个从 0 开始的列表(如数组)时,非常方便地从0数到列表的长度。

let names= ["Anna","Alex","Brian","Jack"]

let count=names.count

for i in 0..<count {

??? print("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

Note that the array contains four items, but 0..<coount only counts as far as3(the index of the last item in the array), because it is a half-open range. For more on arrays, seeArrays.

数组有 4 个元素,但0..<count 只数到3(最后一个元素的下标),因为它是半开区间。关于数组,请查阅数组。

Logical Operators (逻辑运算符)

Logical operatorsmodify or combine the Boolean logic valuestrueandfalse. Swift supports the three standard logical operators found in C-based languages:

逻辑运算符的操作对象是逻辑布尔值。Swift 支撑基于 C 语言的三个标准逻辑运算。

Logical NOT (!a)

Logical AND (a && b)

Logical OR (a || b)

Logical NOT Operator (逻辑非运算符)

Thelogical NOT operator(!a) inverts a Boolean value so thattruebecomesfalse, andfalsebecomestrue.

逻辑非运算符(!a)对一个布尔值取反,使得true变false,false变true。

The logical NOT operator is a prefix operator, and appears immediately before the value it operates on, without any white space. It can be read as “nota”, as seen in the following example:

逻辑非运算符是前缀运算符,并且紧接在其操作的值之前出现,没有任何空格。它可以读作“nota”,如下面的例子所示:

let allowedEntry=false

if !allowedEntry{

??? print("ACCESS DENIED")

}

// Prints "ACCESS DENIED"

The phraseif !allowedEntrycan be read as “if not allowed entry.” The subsequent line is only executed if “not allowed entry” is true; that is, ifallowedEntryisfalse.

if !allowedEntry语句可以读作「如果非 allowedEntry」,接下一行代码只有在「非 allowedEntry」为true,即allowEntry为false时被实行。

As in this example, careful choice of Boolean constant and variable names can help to keep code readable and concise, while avoiding double negatives or confusing logic statements.

在示例代码中,小心地选择布尔常量或变量有助于代码的可读性,并且避免使用双重逻辑非运算,或混乱的逻辑语句。

Logical AND Operator (逻辑与运算符)

Thelogical AND operator(a && b) creates logical expressions where both values must betruefor the overall expression to also betrue.

逻辑与运算符(a && b)表达了只有a和b的值都为true时,整个表达式的值才会是true。

If either value isfalse, the overall expression will also befalse. In fact, if thefirstvalue isfalse, the second value won’t even be evaluated, because it can’t possibly make the overall expression equate totrue. This is known asshort-circuit evaluation.

只要任意一个值为false,整个表达式的值就为false。事实上,如果第一个值为false,那么是不去计算第二个值的,因为它已经不可能影响整个表达式的结果了。这被称做短路计算(short-circuit evaluation)

This example considers twoBoolvalues and only allows access if both values are true:

以下例子,只有两个Bool值都为true的时候才允许进入 if:

let enteredDoorCode=true

let passedRetinaScan=false

if enteredDoorCode && passedRetinaScan {

?? print("Welcome!")

}else{

??? print("ACCESS DENIED")

}

// Prints "ACCESS DENIED"

Logical OR Operator

Thelogical OR operator(a || b) is an infix operator made from two adjacent pipe characters. You use it to create logical expressions in which onlyoneof the two values has to betruefor the overall expression to betrue.

逻辑或运算符(a || b)是一个由两个连续的|组成的中置运算符。它表示了两个逻辑表达式的其中一个为true,整个表达式就为true。

Like the Logical AND operator above, the Logical OR operator uses short-circuit evaluation to consider its expressions. If the left side of a Logical OR expression istrue, the right side is not evaluated, because it cannot change the outcome of the overall expression.

同逻辑与运算符类似,逻辑或也是「短路计算」的,当左端的表达式为true时,将不计算右边的表达式了,因为它不可能改变整个表达式的值了。

In the example below, the firstBoolvalue (hasDoorKey) isfalse, but the second value (knowsOverridePassword) istrue. Because one value istrue, the overall expression also evaluates totrue, and access is allowed:

以下示例代码中,第一个布尔值(hasDoorKey)为false,但第二个值(knowsOverridePassword)为true,所以整个表达是true,于是允许进入:

let hasDoorKey=false

let knowsOverridePassword=true

if hasDoorKey||knowsOverridePassword {

??? print("Welcome!")

} else {

??? print("ACCESS DENIED")

}

// Prints "Welcome!"

Combining Logical Operators (逻辑运算符组合运算)

You can combine multiple logical operators to create longer compound expressions:

大家可以组合多个逻辑运算符来表达一个复合逻辑:

if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {

??? print("Welcome!")

} else {

??? print("ACCESS DENIED")

}

// Prints "Welcome!"

This example uses multiple&&and||operators to create a longer compound expression. However, the&&and||operators still operate on only two values, so this is actually three smaller expressions chained together. The example can be read as:

这个例子使用了含多个&&和||的复合逻辑。但无论怎样,&&和||始终只能操作两个值。所以这实际是三个简单逻辑连续操作的结果。大家来解读一下:

If we’ve entered the correct door code and passed the retina scan, or if we have a valid door key, or if we know the emergency override password, then allow access.

如果大家输入了正确的密码并通过了视网膜扫描,或者大家有一把有效的钥匙,又或者大家知道紧急情况下重置的密码,大家就能把门打开进入。

Based on the values ofenteredDoorCode,passedRetinaScan, andhasDoorKey, the first two subexpressions arefalse. However, the emergency override password is known, so the overall compound expression still evaluates totrue.

前两种情况,大家都不满足,所以前两个简单逻辑的结果是false,但是大家是知道紧急情况下重置的密码的,所以整个复杂表达式的值还是true。

Note

The Swift logical operators&&and||are left-associative, meaning that compound expressions with multiple logical operators evaluate the leftmost subexpression first.

Swift 逻辑操作符&&和||是左结合的,这意味着拥有多元逻辑操作符的复合表达式优先计算最左边的子表达式。

Explicit Parentheses

It is sometimes useful to include parentheses when they are not strictly needed, to make the intention of a complex expression easier to read. In the door access example above, it is useful to add parentheses around the first part of the compound expression to make its intent explicit:

为了一个复杂表达式更容易读懂,在合适的地方使用括号来明确优先级是很有效的,虽然它并非必要的。在上个关于门的权限的例子中,大家给第一个部分加个括号,使它看起来逻辑更明确:

if (enteredDoorCode&&passedRetinaScan) || hasDoorKey || knowsOverridePassword {

??? print("Welcome!")

}else{

??? print("ACCESS DENIED")

}

// Prints "Welcome!"

The parentheses make it clear that the first two values are considered as part of a separate possible state in the overall logic. The output of the compound expression doesn’t change, but the overall intention is clearer to the reader. Readability is always preferred over brevity; use parentheses where they help to make your intentions clear.

这括号使得前两个值被看成整个逻辑表达中独立的一个部分。虽然有括号和没括号的输出结果是一样的,但对于读代码的人来说有括号的代码更清晰。可读性比简洁性更重要,请在可以让你代码变清晰的地方加个括号吧!

推荐阅读更多精彩内容