在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ 基本運(yùn)算符
方法 - Methods
關(guān)于 Swift
下標(biāo)腳本(Subscripts)
類和結(jié)構(gòu)體
類型轉(zhuǎn)換(Type Casting)
控制流
析構(gòu)過程(Deinitialization)
集合類型 (Collection Types)
構(gòu)造過程(Initialization)
Optional Chaining
枚舉(Enumerations)
自動引用計(jì)數(shù)
繼承(Inheritance)
擴(kuò)展(Extensions)
泛型
字符串和字符(Strings and Characters)
函數(shù)(Functions)
高級運(yùn)算符
訪問控制
基本運(yùn)算符
嵌套類型
閉包(Closures)
協(xié)議
屬性 (Properties)

基本運(yùn)算符

運(yùn)算符是檢查、改變、合并值的特殊符號或短語。例如,加號+將兩個數(shù)相加(如let i = 1 + 2)。復(fù)雜些的運(yùn)算例如邏輯與運(yùn)算符&&(如if enteredDoorCode && passedRetinaScan),或讓 i 值加1的便捷自增運(yùn)算符++i等。

Swift 支持大部分標(biāo)準(zhǔn) C 語言的運(yùn)算符,且改進(jìn)許多特性來減少常規(guī)編碼錯誤。如:賦值符(=)不返回值,以防止把想要判斷相等運(yùn)算符(==)的地方寫成賦值符導(dǎo)致的錯誤。算術(shù)運(yùn)算符(+,-,*,/,%等)會檢測并不允許值溢出,以此來避免保存變量時由于變量大于或小于其類型所能承載的范圍時導(dǎo)致的異常結(jié)果。當(dāng)然允許你使用 Swift 的溢出運(yùn)算符來實(shí)現(xiàn)溢出。詳情參見溢出運(yùn)算符。

區(qū)別于 C 語言,在 Swift 中你可以對浮點(diǎn)數(shù)進(jìn)行取余運(yùn)算(%),Swift 還提供了 C 語言沒有的表達(dá)兩數(shù)之間的值的區(qū)間運(yùn)算符(a..<ba...b),這方便我們表達(dá)一個區(qū)間內(nèi)的數(shù)值。

本章節(jié)只描述了 Swift 中的基本運(yùn)算符,高級運(yùn)算符包含了高級運(yùn)算符,及如何自定義運(yùn)算符,及如何進(jìn)行自定義類型的運(yùn)算符重載。

術(shù)語

運(yùn)算符有一元、二元和三元運(yùn)算符。

  • 一元運(yùn)算符對單一操作對象操作(如-a)。一元運(yùn)算符分前置運(yùn)算符和后置運(yùn)算符,前置運(yùn)算符需緊排操作對象之前(如!b),后置運(yùn)算符需緊跟操作對象之后(如i++)。
  • 二元運(yùn)算符操作兩個操作對象(如2 + 3),是中置的,因?yàn)樗鼈兂霈F(xiàn)在兩個操作對象之間。
  • 三元運(yùn)算符操作三個操作對象,和 C 語言一樣,Swift 只有一個三元運(yùn)算符,就是三目運(yùn)算符(a ? b : c)。

受運(yùn)算符影響的值叫操作數(shù),在表達(dá)式1 + 2中,加號+是二元運(yùn)算符,它的兩個操作數(shù)是值12

賦值運(yùn)算符

賦值運(yùn)算(a = b),表示用b的值來初始化或更新a的值:

    let b = 10
    var a = 5
    a = b
    // a 現(xiàn)在等于 10

如果賦值的右邊是一個多元組,它的元素可以馬上被分解多個常量或變量:

    let (x, y) = (1, 2)
    // 現(xiàn)在 x 等于 1, y 等于 2

與 C 語言和 Objective-C 不同,Swift 的賦值操作并不返回任何值。所以以下代碼是錯誤的:

    if x = y {
        // 此句錯誤, 因?yàn)?x = y 并不返回任何值
    }

這個特性使你無法把(==)錯寫成(=),由于if x = y是錯誤代碼,Swift幫你避免此類錯誤的的發(fā)生。

算術(shù)運(yùn)算符

Swift 中所有數(shù)值類型都支持了基本的四則算術(shù)運(yùn)算:

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

與 C 語言和 Objective-C 不同的是,Swift 默認(rèn)情況下不允許在數(shù)值運(yùn)算中出現(xiàn)溢出情況。但是你可以使用 Swift 的溢出運(yùn)算符來實(shí)現(xiàn)溢出運(yùn)算(如a &+ b)。詳情參見溢出運(yùn)算符。

加法運(yùn)算符也可用于String的拼接:

    "hello, " + "world"  // 等于 "hello, world"

兩個Character值或一個String和一個Character值,相加會生成一個新的String值:

let dog: Character = "d"
let cow: Character = "c"
let dogCow = dog + cow
// 譯者注: 原來的引號內(nèi)是很可愛的小狗和小牛, 但win os下不支持表情字符, 所以改成了普通字符
// dogCow 現(xiàn)在是 "dc"

詳情參見字符,字符串的拼接

求余運(yùn)算符

求余運(yùn)算(a % b)是計(jì)算b的多少倍剛剛好可以容入a,返回多出來的那部分(余數(shù))。

注意:
求余運(yùn)算(%)在其他語言也叫取模運(yùn)算。然而嚴(yán)格說來,我們看該運(yùn)算符對負(fù)數(shù)的操作結(jié)果,"求余"比"取模"更合適些。

我們來談?wù)勅∮嗍窃趺椿厥?,?jì)算9 % 4,你先計(jì)算出4的多少倍會剛好可以容入9中:

http://wiki.jikexueyuan.com/project/swift-language-guide/images/Basic_Operators_1.png" alt="Image of Basic Operators_1.png" />

2倍,非常好,那余數(shù)是1(用橙色標(biāo)出)

在 Swift 中可以表達(dá)為:

    9 % 4    // 等于 1

為了得到a % b的結(jié)果,%計(jì)算了以下等式,并輸出余數(shù)作為結(jié)果:

a = (b × 倍數(shù)) + 余數(shù)

當(dāng)倍數(shù)取最大值的時候,就會剛好可以容入a中。

94代入等式中,我們得1

9 = (4 × 2) + 1

同樣的方法,我來們計(jì)算 -9 % 4

    -9 % 4   // 等于 -1

-94代入等式,-2是取到的最大整數(shù):

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

余數(shù)是-1。

在對負(fù)數(shù)b求余時,b的符號會被忽略。這意味著 a % ba % -b的結(jié)果是相同的。

浮點(diǎn)數(shù)求余計(jì)算

不同于 C 語言和 Objective-C,Swift 中是可以對浮點(diǎn)數(shù)進(jìn)行求余的。

    8 % 2.5 // 等于 0.5

這個例子中,8除于2.5等于30.5,所以結(jié)果是一個Double0.5

http://wiki.jikexueyuan.com/project/swift-language-guide/images/Basic_Operators_2.png" alt="Image of Basic Operators_2.png" />

自增和自減運(yùn)算

和 C 語言一樣,Swift 也提供了對變量本身加1或減1的自增(++)和自減(--)的縮略算符。其操作對象可以是整形和浮點(diǎn)型。 ?

    var i = 0
    ++i      // 現(xiàn)在 i = 1

每調(diào)用一次++ii的值就會加1。實(shí)際上,++ii = i + 1的簡寫,而--ii = i - 1的簡寫。

++--既可以用作前置運(yùn)算又可以用作后置運(yùn)算。++ii++,--ii--都是有效的寫法。

我們需要注意的是這些運(yùn)算符即可修改了i的值也可以返回i的值。如果你只想修改i的值,那你就可以忽略這個返回值。但如果你想使用返回值,你就需要留意前置和后置操作的返回值是不同的,她們遵循以下原則:

  • 當(dāng)++前置的時候,先自増?jiān)俜祷亍?/li>
  • 當(dāng)++后置的時候,先返回再自增。

例如:

    var a = 0
    let b = ++a // a 和 b 現(xiàn)在都是 1
    let c = a++ // a 現(xiàn)在 2, 但 c 是 a 自增前的值 1

上述例子,let b = ++a先把a加1了再返回a的值。所以ab都是新值1。

let c = a++,是先返回了a的值,然后a才加1。所以c得到了a的舊值1,而a加1后變成2。

除非你需要使用i++的特性,不然推薦你使用++i--i,因?yàn)橄刃薷暮蠓祷剡@樣的行為更符合我們的邏輯。

一元負(fù)號運(yùn)算符

數(shù)值的正負(fù)號可以使用前綴-(即一元負(fù)號)來切換:

    let three = 3
    let minusThree = -three       // minusThree 等于 -3
    let plusThree = -minusThree   // plusThree 等于 3, 或 "負(fù)負(fù)3"

一元負(fù)號(-)寫在操作數(shù)之前,中間沒有空格。

一元正號運(yùn)算符

一元正號(+)不做任何改變地返回操作數(shù)的值。

    let minusSix = -6
    let alsoMinusSix = +minusSix  // alsoMinusSix 等于 -6

雖然一元+什么都不會改變,但當(dāng)你在使用一元負(fù)號來表達(dá)負(fù)數(shù)時,你可以使用一元正號來表達(dá)正數(shù),如此你的代碼會具有對稱美。

復(fù)合賦值(Compound Assignment Operators)

如同強(qiáng)大的 C 語言,Swift 也提供把其他運(yùn)算符和賦值運(yùn)算(=)組合的復(fù)合賦值運(yùn)算符,組合加運(yùn)算(+=)是其中一個例子:

    var a = 1
    a += 2 
    // a 現(xiàn)在是 3

表達(dá)式a += 2a = a + 2的簡寫,一個組合加運(yùn)算就是把加法運(yùn)算和賦值運(yùn)算組合成進(jìn)一個運(yùn)算符里,同時完成兩個運(yùn)算任務(wù)。

注意:
復(fù)合賦值運(yùn)算沒有返回值,let b = a += 2這類代碼是錯誤。這不同于上面提到的自增和自減運(yùn)算符。

表達(dá)式章節(jié)里有復(fù)合運(yùn)算符的完整列表。 ?

比較運(yùn)算符

所有標(biāo)準(zhǔn) C 語言中的比較運(yùn)算都可以在 Swift 中使用。

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

注意: Swift 也提供恒等===和不恒等!==這兩個比較符來判斷兩個對象是否引用同一個對象實(shí)例。更多細(xì)節(jié)在類與結(jié)構(gòu)。

每個比較運(yùn)算都返回了一個標(biāo)識表達(dá)式是否成立的布爾值:

    1 == 1   // true, 因?yàn)?1 等于 1
    2 != 1   // true, 因?yàn)?2 不等于 1
    2 > 1    // true, 因?yàn)?2 大于 1
    1 < 2    // true, 因?yàn)?1 小于2
    1 >= 1   // true, 因?yàn)?1 大于等于 1
    2 <= 1   // false, 因?yàn)?2 并不小于等于 1

比較運(yùn)算多用于條件語句,如if條件:

    let name = "world"
    if name == "world" {
        println("hello, world")
    } else {
        println("I'm sorry \(name), but I don't recognize you")
    }
    // 輸出 "hello, world", 因?yàn)?`name` 就是等于 "world"

關(guān)于if語句,請看控制流。

三目運(yùn)算符(Ternary Conditional Operator)

三目運(yùn)算符的特殊在于它是有三個操作數(shù)的運(yùn)算符,它的原型是 問題 ? 答案1 : 答案2。它簡潔地表達(dá)根據(jù)問題成立與否作出二選一的操作。如果問題成立,返回答案1的結(jié)果; 如果不成立,返回答案2的結(jié)果。

三目運(yùn)算符是以下代碼的縮寫形式:

    if question: {
        answer1
    } else {
        answer2
    }

這里有個計(jì)算表格行高的例子。如果有表頭,那行高應(yīng)比內(nèi)容高度要高出50像素; 如果沒有表頭,只需高出20像素。

    let contentHeight = 40
    let hasHeader = true
    let rowHeight = contentHeight + (hasHeader ? 50 : 20)
    // rowHeight 現(xiàn)在是 90

這樣寫會比下面的代碼簡潔:

    let contentHeight = 40
    let hasHeader = true
    var rowHeight = contentHeight
    if hasHeader {
        rowHeight = rowHeight + 50
    } else {
        rowHeight = rowHeight + 20
    }
    // rowHeight 現(xiàn)在是 90

第一段代碼例子使用了三目運(yùn)算,所以一行代碼就能讓我們得到正確答案。這比第二段代碼簡潔得多,無需將rowHeight定義成變量,因?yàn)樗闹禑o需在if語句中改變。

三目運(yùn)算提供有效率且便捷的方式來表達(dá)二選一的選擇。需要注意的事,過度使用三目運(yùn)算符會使簡潔的代碼變的難懂。我們應(yīng)避免在一個組合語句中使用多個三目運(yùn)算符。

空合運(yùn)算符(Nil Coalescing Operator)

空合運(yùn)算符(a ?? b)將對可選類型a進(jìn)行空判斷,如果a包含一個值就進(jìn)行解封,否則就返回一個默認(rèn)值b.這個運(yùn)算符有兩個條件:

  • 表達(dá)式a必須是Optional類型
  • 默認(rèn)值b的類型必須要和a存儲值的類型保持一致

空合并運(yùn)算符是對以下代碼的簡短表達(dá)方法

    a != nil ? a! : b

上述代碼使用了三目運(yùn)算符。當(dāng)可選類型a的值不為空時,進(jìn)行強(qiáng)制解封(a!)訪問a中值,反之當(dāng)a中值為空時,返回默認(rèn)值b。無疑空合運(yùn)算符(??)提供了一種更為優(yōu)雅的方式去封裝條件判斷和解封兩種行為,顯得簡潔以及更具可讀性。

注意: 如果a為非空值(non-nil),那么值b將不會被估值。這也就是所謂的短路求值。

下文例子采用空合并運(yùn)算符,實(shí)現(xiàn)了在默認(rèn)顏色名和可選自定義顏色名之間抉擇:

    let defaultColorName = "red"
    var userDefinedColorName:String?   //默認(rèn)值為nil

    var colorNameToUse = userDefinedColorName ?? defaultColorName
    //userDefinedColorName的值為空 ,所以colorNameToUse的值為`red`

userDefinedColorName變量被定義為一個可選字符串類型,默認(rèn)值為nil。由于userDefinedColorName是一個可選類型,我們可以使用空合運(yùn)算符去判斷其值。在上一個例子中,通過空合運(yùn)算符為一個名為colorNameToUse的變量賦予一個字符串類型初始值。 由于userDefinedColorName值為空,因此表達(dá)式userDefinedColorName ?? defaultColorName返回默認(rèn)值,即red。

另一種情況,分配一個非空值(non-nil)給 userDefinedColorName,再次執(zhí)行空合運(yùn)算,運(yùn)算結(jié)果為封包在userDefaultColorName中的值,而非默認(rèn)值。

    userDefinedColorName = "green"
    colorNameToUse = userDefinedColorName ?? defaultColorName
    //userDefinedColorName非空,因此colorNameToUsede的值為綠色

區(qū)間運(yùn)算符

Swift 提供了兩個方便表達(dá)一個區(qū)間的值的運(yùn)算符。

閉區(qū)間運(yùn)算符

閉區(qū)間運(yùn)算符(a...b)定義一個包含從ab(包括ab)的所有值的區(qū)間,b必須大于a。 ? 閉區(qū)間運(yùn)算符在迭代一個區(qū)間的所有值時是非常有用的,如在for-in循環(huán)中:

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

關(guān)于for-in,請看控制流。

半開區(qū)間運(yùn)算符

半開區(qū)間(a..<b)定義一個從ab但不包括b的區(qū)間。 之所以稱為半開區(qū)間,是因?yàn)樵搮^(qū)間包含第一個值而不包括最后的值。

半開區(qū)間的實(shí)用性在于當(dāng)你使用一個0始的列表(如數(shù)組)時,非常方便地從0數(shù)到列表的長度。

    let names = ["Anna", "Alex", "Brian", "Jack"]
    let count = names.count
    for i in 0..<count {
        println("第 \(i + 1) 個人叫 \(names[i])")
    }
    // 第 1 個人叫 Anna
    // 第 2 個人叫 Alex
    // 第 3 個人叫 Brian
    // 第 4 個人叫 Jack

數(shù)組有4個元素,但0..<count只數(shù)到3(最后一個元素的下標(biāo)),因?yàn)樗前腴_區(qū)間。關(guān)于數(shù)組,請查閱數(shù)組。

邏輯運(yùn)算

邏輯運(yùn)算的操作對象是邏輯布爾值。Swift 支持基于 C 語言的三個標(biāo)準(zhǔn)邏輯運(yùn)算。

  • 邏輯非(!a
  • 邏輯與(a && b
  • 邏輯或(a || b

邏輯非

邏輯非運(yùn)算(!a)對一個布爾值取反,使得truefalsefalsetrue。

它是一個前置運(yùn)算符,需出現(xiàn)在操作數(shù)之前,且不加空格。讀作非 a,例子如下:

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

if !allowedEntry語句可以讀作 "如果 非 alowed entry。",接下一行代碼只有在如果 "非 allow entry" 為true,即allowEntryfalse時被執(zhí)行。

在示例代碼中,小心地選擇布爾常量或變量有助于代碼的可讀性,并且避免使用雙重邏輯非運(yùn)算,或混亂的邏輯語句。

邏輯與

邏輯與(a && b)表達(dá)了只有ab的值都為true時,整個表達(dá)式的值才會是true

只要任意一個值為false,整個表達(dá)式的值就為false。事實(shí)上,如果第一個值為false,那么是不去計(jì)算第二個值的,因?yàn)樗呀?jīng)不可能影響整個表達(dá)式的結(jié)果了。這被稱做 "短路計(jì)算(short-circuit evaluation)"。

以下例子,只有兩個Bool值都為true的時候才允許進(jìn)入:

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

邏輯或

邏輯或(a || b)是一個由兩個連續(xù)的|組成的中置運(yùn)算符。它表示了兩個邏輯表達(dá)式的其中一個為true,整個表達(dá)式就為true。

同邏輯與運(yùn)算類似,邏輯或也是"短路計(jì)算"的,當(dāng)左端的表達(dá)式為true時,將不計(jì)算右邊的表達(dá)式了,因?yàn)樗豢赡芨淖冋麄€表達(dá)式的值了。

以下示例代碼中,第一個布爾值(hasDoorKey)為false,但第二個值(knowsOverridePassword)為true,所以整個表達(dá)是true,于是允許進(jìn)入:

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

邏輯運(yùn)算符組合計(jì)算

我們可以組合多個邏輯運(yùn)算來表達(dá)一個復(fù)合邏輯:

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

這個例子使用了含多個&&||的復(fù)合邏輯。但無論怎樣,&&||始終只能操作兩個值。所以這實(shí)際是三個簡單邏輯連續(xù)操作的結(jié)果。我們來解讀一下:

如果我們輸入了正確的密碼并通過了視網(wǎng)膜掃描; 或者我們有一把有效的鑰匙; 又或者我們知道緊急情況下重置的密碼,我們就能把門打開進(jìn)入。

前兩種情況,我們都不滿足,所以前兩個簡單邏輯的結(jié)果是false,但是我們是知道緊急情況下重置的密碼的,所以整個復(fù)雜表達(dá)式的值還是true。

使用括號來明確優(yōu)先級

為了一個復(fù)雜表達(dá)式更容易讀懂,在合適的地方使用括號來明確優(yōu)先級是很有效的,雖然它并非必要的。在上個關(guān)于門的權(quán)限的例子中,我們給第一個部分加個括號,使用它看起來邏輯更明確:

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

這括號使得前兩個值被看成整個邏輯表達(dá)中獨(dú)立的一個部分。雖然有括號和沒括號的輸出結(jié)果是一樣的,但對于讀代碼的人來說有括號的代碼更清晰。可讀性比簡潔性更重要,請?jiān)诳梢宰屇愦a變清晰地地方加個括號吧!

上一篇:屬性 (Properties)下一篇:協(xié)議