Swift002-運(yùn)算符和流程控制語(yǔ)句

Swift002-運(yùn)算符和流程控制語(yǔ)句

運(yùn)算符

Swift支持大多數(shù)標(biāo)準(zhǔn)C運(yùn)算符闲坎,并有所改進(jìn)崭闲。

  • 賦值運(yùn)算符(=)不返回值吝岭,以防止在相等運(yùn)算(==)意圖時(shí)錯(cuò)誤地使用它三痰。
  • 算術(shù)運(yùn)算符(+,-窜管,*散劫,/,%等)檢測(cè)和禁止值溢出幕帆,避免數(shù)據(jù)比類(lèi)型允許范圍更大或更小
  • 在面對(duì)數(shù)值溢出行為可以選擇使用溢出運(yùn)算符舷丹,在溢出運(yùn)算符中描述。
  • 提供了在C中不存在的區(qū)間運(yùn)算符蜓肆,如a..<b和a...b表示一系列值范圍的快捷方式。

按目標(biāo)數(shù)量分類(lèi)

按操作數(shù)分為:一元運(yùn)算符谋币、二元運(yùn)算符仗扬、三元運(yùn)算符(也有習(xí)慣成目,如三目運(yùn)算符)

  • 一元運(yùn)算符 作用于單個(gè)目標(biāo)(在前面則前綴一元運(yùn)算符蕾额,后面則后綴一元運(yùn)算符)早芭,如:-a !a a!
  • 二元運(yùn)算符 作用于兩個(gè)目標(biāo),是中綴運(yùn)算符诅蝶, 如:a+b
  • 三元運(yùn)算符 作用于三個(gè)目標(biāo)(Swift同OC一樣只有一個(gè)三元運(yùn)算符 a?b:c)

按功能作用分類(lèi)

  • 賦值運(yùn)算符 =
  • 算術(shù)運(yùn)算符 + - * / % (Swift默認(rèn)禁止值溢出退个,但可使用溢出符號(hào)選擇溢出行為: a &+ b募壕,另外+可用于String連接)
  • 一元加減運(yùn)算符 + - (let a = -10086)
  • 復(fù)合賦值運(yùn)算符 += -=
  • 比較運(yùn)算符 == != > < >= <= (Swift還提供了恒等運(yùn)算符 === !==)
  • 三元條件運(yùn)算符 ?: (可以將if else 進(jìn)行簡(jiǎn)化)
  • Nil-Coalescing運(yùn)算符 (a??b 表示 (a!=nil)?(a!):b, a!表示必然有值強(qiáng)制解包,a不為nil則不管b语盈,這也稱(chēng)為短路評(píng)估)
  • 區(qū)間運(yùn)算符 (a...b 區(qū)間表示[a,b]舱馅,a..<b區(qū)間表示[a,b),單向區(qū)間a...和..<b,分別表示a到結(jié)尾和起始到b但不包含b)
  • 邏輯運(yùn)算符 ! && || (分別非 且 或)

注:
reversed()結(jié)合區(qū)間運(yùn)算符則倒序

for i in (0..<10).reversed() {
    print(i)
}
// 9 8 7 6 5 4 3 2 1 0

字符串范圍結(jié)合區(qū)間運(yùn)算符

let msg = "www.google.com"
// 不使用區(qū)間運(yùn)算符
let index1 = msg.index(msg.startIndex, offsetBy: 4)
let index2 = msg.index(msg.startIndex, offsetBy: 6)
let range1 = Range(uncheckedBounds: (lower: index1, upper: index2))
let subStr1 = msg.substring(with: range) 
print(subStr1)
// 使用區(qū)間運(yùn)算符
let range2 = msg.index(msg.startIndex, offsetBy: 4)..<msg.index(msg.startIndex, offsetBy: 6)
let subStr2 = msg.substring(with: range2) 
print(subStr2)

區(qū)間運(yùn)算符除了返回一個(gè)Range外刀荒,還可以接受Comparable的輸入代嗤,返回ClosedInterval或HalfOpenInterval

// 我們可以用這個(gè)特性檢查字符串里的字符是不是都是合法字符(如是不是都是小寫(xiě))
let words = "Welcome!"
let interval = "a"..."z"
for c in words.characters {
    if !interval.contains(String(c)){
            print("\(c)不是小寫(xiě)字母")
    }
}
// W不是小寫(xiě)字母 !不是小寫(xiě)字母

流程控制語(yǔ)句

if... (if...else...)

public class func testIf() {
        let a = 1
        let b = 2
        // 可以不帶括號(hào)
        if a < b {
            print("a>b")
        }
    }
let settingURL = URL(string: UIApplication.openSettingsURLString)!
if UIApplication.shared.canOpenURL(settingURL) {
    if #available(iOS 10, *) {
        UIApplication.shared.open(settingURL, options: [:], completionHandler: nil)
    } else {
        UIApplication.shared.openURL(settingURL)
    }
}

switch

public class func testSwitch() {
        // Swift中不需在用break跳出switch。若想用C風(fēng)格的落入特性缠借,需給case分支插入fallthrough語(yǔ)句
        let fruit = "apple"
        switch fruit {
        case "apple": print("good"); fallthrough // 用分號(hào)結(jié)束寫(xiě)到同一行
        case "banana","orange": print("great")
        default: print("bad")
        }
        // case分支還可以進(jìn)行區(qū)間匹配
        let age = 5
        switch age {
        case 0...11: print("少兒")
        case 12...18: print("少年")
        default: print("其他")
        }
        // case分支同樣支持單側(cè)區(qū)間匹配
        let num = -5
        switch num {
        case ..<0: print("負(fù)數(shù)")
        case 0...: print("正數(shù)")
        default: print("0")
        }
        // 使用元組匹配(如:判斷屬于哪個(gè)象限)
        let point = (2,2)
        switch point {
        case (0,0): print("坐標(biāo)在原點(diǎn)")
        case (_,0): print("坐標(biāo)在x軸上")
        case (0,_): print("坐標(biāo)在y軸上")
        default: print("在象限區(qū)域")
        }
        // case中還可以使用where關(guān)鍵字來(lái)做額外的判斷條件
        let height = 1.72
        switch height{
        case 1...3 where height == 1.72:  print("case 1")
        case 1...3 where height == 2: print("case 2")
        default: print("default")
        }
        // 值綁定
        let anotherPoint = (2, 0)
        switch anotherPoint {
        case (let x, 0):
            print("on the x-axis with an x value of \(x)")
        case (0, let y):
            print("on the y-axis with a y value of \(y)")
        case let (x, y):
            print("somewhere else at (\(x), \(y))")
        }
        // on the x-axis with an x value of 2
        // 復(fù)合案例
        let someCharacter: Character = "e"
        switch someCharacter {
        case "a", "e", "i", "o", "u":
            print("\(someCharacter) is a vowel")
        case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
             "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
            print("\(someCharacter) is a consonant")
        default:
            print("\(someCharacter) is not a vowel or a consonant")
        }
        // e is a vowel
        // 復(fù)合案例 結(jié)合 值綁定
        let stillAnotherPoint = (9, 0)
        switch stillAnotherPoint {
        case (let distance, 0), (0, let distance):
            print("On an axis, \(distance) from the origin")
        default:
            print("Not on an axis")
        }
        // On an axis, 9 from the origin
    }

for

public class func testFor() {
        // C-style for statement has been removed in Swift 3
        //for var i=1; i<100; i++ {
        //  print("\(i)")
        //}
        // for-in
        for chare in "Google" {
            print(chare)
        }
        // forEach
        (1...10).forEach {
            print($0)
        }
    }

控制轉(zhuǎn)移語(yǔ)句

  • continue

continue語(yǔ)句告訴循環(huán)停止當(dāng)前循環(huán)不再往下執(zhí)行干毅,進(jìn)入下次循環(huán)。即“完成了當(dāng)前的循環(huán)迭代”而沒(méi)有離開(kāi)循環(huán)泼返。

public class func testContinue() {
        let startStr = "www.google.com www.apple.com"
        var endStr = ""
        let charactersToRemove: [Character] = ["a", "e", "i", "o", "u", " "]
        for character in startStr {
            if charactersToRemove.contains(character) {
                continue
            }
            endStr.append(character)
        }
        print(endStr)  // www.ggl.cmwww.ppl.cm
    }
  • break

break語(yǔ)句立即結(jié)束整個(gè)控制流語(yǔ)句的執(zhí)行硝逢,盡管break在Swift中不需要,但仍可用來(lái)中斷匹配绅喉。

public class func testBreak() {
        let numberSymbol: Character = "三"
        var possibleIntegerValue: Int?
        switch numberSymbol {
        case "1", "?", "一", "?":
            possibleIntegerValue = 1
        case "2", "?", "二", "?":
            possibleIntegerValue = 2
        case "3", "?", "三", "?":
            possibleIntegerValue = 3
        case "4", "?", "四", "?":
            possibleIntegerValue = 4
        default:
            break
        }
        if let integerValue = possibleIntegerValue {
            print("The integer value of \(numberSymbol) is \(integerValue).")
        } else {
            print("An integer value could not be found for \(numberSymbol).")
        }
        // The integer value of 三 is 3.
    }
  • fallthrough

在Swift中渠鸽,switch語(yǔ)句不會(huì)落入每個(gè)案例的底部并進(jìn)入下一個(gè)案例。也就是說(shuō)霹疫,switch一旦第一個(gè)匹配的案例完成拱绑,整個(gè)語(yǔ)句就完成了它的執(zhí)行。相反丽蝎,C要求break在每個(gè)switch案例的末尾插入一個(gè)明確的語(yǔ)句猎拨,以防止通過(guò)。避免默認(rèn)的下降意味著Swift switch語(yǔ)句比C中的對(duì)應(yīng)語(yǔ)句更簡(jiǎn)潔和可預(yù)測(cè)屠阻,因此它們避免switch錯(cuò)誤地執(zhí)行多個(gè)案例红省。
如果需要C樣式的直通行為,則可以使用fallthrough關(guān)鍵字逐個(gè)選擇加入此行為国觉。以下示例fallthrough用于創(chuàng)建數(shù)字的文本描述吧恃。

  • return

用于提前退出,不再執(zhí)行代碼段中代碼

public class func testReturn(_ fruit:[String: String]) {
        guard let price = fruit["price"] else {
            return
        }
        print("price is \(price)")
    }
  • throw

守護(hù)關(guān)鍵字 guard

其實(shí)是if...else...變種麻诀,滿(mǎn)足guard語(yǔ)句的條件則跳過(guò)else向下執(zhí)行痕寓,否則執(zhí)行else中語(yǔ)句
else分支必須轉(zhuǎn)移控制以退出guard語(yǔ)句出現(xiàn)的代碼塊,如return,break蝇闭,continue呻率,或throw,也可以調(diào)用一個(gè)函數(shù)或方法不返回呻引,如fatalError()礼仗。

public class func testReturn(_ fruit:[String: String]) {
        guard let price = fruit["price"] else {
            return
        }
        guard let name = fruit["name"] else {
            fatalError("致命錯(cuò)誤:不存在name鍵值")
        }
        print("price is \(price)")
    }

自定義致命錯(cuò)誤fatalError

public class func testFatalError(){
        // (1) fatal error發(fā)生時(shí),defer是不會(huì)執(zhí)行的
        // (2) catch 不到 fatal error
        defer {
            print("defer here") // 不執(zhí)行
        }
        do {
            try _throwsMyFatalError() // 產(chǎn)生fatal error
        } catch let err {
            print("in MyFatalError catch section \(err)") // 這一行進(jìn)不了
        }
    }
    private class func _throwsMyFatalError() throws {
        fatalError("my fatal error here!")
    }

標(biāo)簽語(yǔ)句

在Swift中,可以在其他循環(huán)和條件語(yǔ)句中嵌套循環(huán)和條件語(yǔ)句元践,以創(chuàng)建復(fù)雜的控制流結(jié)構(gòu)韭脊。但是,循環(huán)和條件語(yǔ)句都可以使用break語(yǔ)句過(guò)早地結(jié)束執(zhí)行单旁。因此沪羔,有時(shí)候明確要求break語(yǔ)句終止的循環(huán)或條件語(yǔ)句是有用的。類(lèi)似地慎恒,如果有多個(gè)嵌套循環(huán)任内,那么明確該continue語(yǔ)句應(yīng)該影響哪個(gè)循環(huán)可能很有用。
要實(shí)現(xiàn)這些目標(biāo)融柬,可以使用語(yǔ)句標(biāo)簽標(biāo)記循環(huán)語(yǔ)句或條件語(yǔ)句死嗦。使用條件語(yǔ)句,可以使用帶標(biāo)簽語(yǔ)句的break語(yǔ)句來(lái)結(jié)束帶標(biāo)簽語(yǔ)句的執(zhí)行粒氧。使用循環(huán)語(yǔ)句越除,可以使用帶有標(biāo)簽語(yǔ)句的break、continue語(yǔ)句來(lái)結(jié)束或繼續(xù)執(zhí)行帶標(biāo)簽的語(yǔ)句外盯。
標(biāo)簽語(yǔ)句通過(guò)在語(yǔ)句相同行上關(guān)鍵字前放置標(biāo)簽名來(lái)指示摘盆,后跟冒號(hào)。這是while循環(huán)的這種語(yǔ)法的一個(gè)例子饱苟,然而所有循環(huán)和switch語(yǔ)句的原理是相同的:

public class func testLabel() {
        let finishIndex = 25
        var currentIndex = 0
        var diceRoll = 0
        gameLoop: while currentIndex != finishIndex {
            diceRoll += 1
            if diceRoll == 7 { diceRoll = 1 }
            switch currentIndex + diceRoll {
            case finishIndex:
                break gameLoop
            case let newSquare where newSquare > finishIndex:
                continue gameLoop
            default:
                currentIndex += diceRoll
            }
        }
    }

運(yùn)算符重載

讓已有的運(yùn)算符對(duì)自定義的類(lèi)(結(jié)構(gòu))進(jìn)行運(yùn)算或重新定義已有運(yùn)算符的運(yùn)算規(guī)則孩擂,這種機(jī)制被稱(chēng)為運(yùn)算符重載。

  • 通過(guò)重載加號(hào)運(yùn)算符箱熬,使自定義的兩個(gè)坐標(biāo)結(jié)構(gòu)體對(duì)象實(shí)現(xiàn)相加
struct CenterPointer{
    var x=0, y=0
}
 
func + (left:CenterPointer, right:CenterPointer) -> CenterPointer{
    return CenterPointer(x:left.x+right.x, y:left.y+right.y)
}
 
let pointer1 = CenterPointer(x:2, y:3)
let pointer2 = CenterPointer(x:4, y:5)
let pointer3 = pointer1 + pointer2
  • 重載判斷運(yùn)算符类垦,實(shí)現(xiàn)判斷自定義類(lèi)型是否相等
func == (left:CenterPointer, right:CenterPointer) -> Bool {
    return (left.x == right.x) && (left.y == right.y)
}
 
func != (left:CenterPointer, right:CenterPointer) -> Bool {
    return !(left == right)
}
  • 組合運(yùn)算符,即將其他運(yùn)算符和賦值運(yùn)算符組合在一起城须,注意把運(yùn)算符左參數(shù)設(shè)置成inout類(lèi)型
func += (left:inout CenterPointer, right:CenterPointer){
    left = left + right
}
 
var pointer1 = CenterPointer(x:2, y:3)
var pointer2 = CenterPointer(x:4, y:5)
pointer1 += pointer2

extension及fatalError

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蚤认,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子糕伐,更是在濱河造成了極大的恐慌砰琢,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件良瞧,死亡現(xiàn)場(chǎng)離奇詭異陪汽,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)褥蚯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)掩缓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人遵岩,你說(shuō)我怎么就攤上這事。” “怎么了尘执?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵舍哄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我誊锭,道長(zhǎng)表悬,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任丧靡,我火速辦了婚禮蟆沫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘温治。我一直安慰自己饭庞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布熬荆。 她就那樣靜靜地躺著舟山,像睡著了一般。 火紅的嫁衣襯著肌膚如雪卤恳。 梳的紋絲不亂的頭發(fā)上累盗,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音突琳,去河邊找鬼若债。 笑死,一個(gè)胖子當(dāng)著我的面吹牛拆融,可吹牛的內(nèi)容都是我干的蠢琳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼冠息,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼挪凑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起逛艰,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤躏碳,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后散怖,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體菇绵,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年镇眷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咬最。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡欠动,死狀恐怖永乌,靈堂內(nèi)的尸體忽然破棺而出惑申,到底是詐尸還是另有隱情,我是刑警寧澤翅雏,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布圈驼,位于F島的核電站,受9級(jí)特大地震影響望几,放射性物質(zhì)發(fā)生泄漏绩脆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一橄抹、第九天 我趴在偏房一處隱蔽的房頂上張望靴迫。 院中可真熱鬧,春花似錦楼誓、人聲如沸玉锌。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)芬沉。三九已至,卻和暖如春阁猜,著一層夾襖步出監(jiān)牢的瞬間丸逸,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工剃袍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留黄刚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓民效,卻偏偏與公主長(zhǎng)得像憔维,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子畏邢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355