基礎(chǔ)運(yùn)算符(Basic Operators)

? ? 運(yùn)算符是一個(gè)特殊的符號(hào)或者短句家卖,你可以用它來(lái)檢查,改變或者組合某一些值。比如飞主,加法運(yùn)算符(+)可以讓2個(gè)數(shù)字相加,像在?let i = 1 + 2 中一樣,有比如邏輯與運(yùn)算符(&&),可以組合2個(gè)布爾值琉朽,就像在 if??true && false?中一樣域帐。

? ? Swfit支持大多數(shù)標(biāo)準(zhǔn)c語(yǔ)言中的運(yùn)算符,還改善了部分功能,用以排除一些常見(jiàn)的編碼錯(cuò)誤悴侵。賦值運(yùn)算符(=)不會(huì)有返回值瞧剖,防止和比較運(yùn)算符(==)混用。術(shù)數(shù)運(yùn)算符(+,-*,/,%等)可免,會(huì)檢測(cè)并防止值溢出抓于。避免在正在處理的值不在對(duì)應(yīng)類型可以存儲(chǔ)的值的范圍之中而出現(xiàn)意料之外的結(jié)果。你可以選擇溢出運(yùn)算符來(lái)選擇值溢出是采取的行為浇借。

? ? Swift也提供了C語(yǔ)言中沒(méi)有的范圍運(yùn)算符捉撮,比如a..<ba...b,這是表示值的范圍的簡(jiǎn)寫。

? ? 這一章只描述Swift中常用的運(yùn)算符妇垢。在高級(jí)運(yùn)算符章節(jié)中巾遭,會(huì)覆蓋Swift的高級(jí)運(yùn)算符,以及如何定義你自己的運(yùn)算符闯估,或者為你自定義的類實(shí)現(xiàn)標(biāo)準(zhǔn)庫(kù)中的運(yùn)算符灼舍。

術(shù)語(yǔ)(Terminology)

? ? 運(yùn)算符分為一元運(yùn)算符,二元運(yùn)算符睬愤,和三元運(yùn)算符:????

? ? 一元運(yùn)算符作用在一個(gè)單獨(dú)的目標(biāo)上片仿,比如(-a)。一元的前綴運(yùn)算符緊跟在要操作的目標(biāo)之前(!b)尤辱。一元的后綴運(yùn)算符緊跟在要操作的目標(biāo)之后(c!)。

? ? 二元運(yùn)算符作用在2個(gè)目標(biāo)上厢岂,比如2 + 3光督。被稱為中綴,因?yàn)樗霈F(xiàn)在2個(gè)目標(biāo)之間塔粒。

? ? 三元運(yùn)算符作用在3個(gè)目標(biāo)之上结借。和C語(yǔ)言一樣,Swift只有一個(gè)三元運(yùn)算符卒茬,也就是三目運(yùn)算符(a ??b : c)

? ? 運(yùn)算符操作的值叫做運(yùn)算單元船老。在表達(dá)式1 + 2中,+ 號(hào)運(yùn)算符是一個(gè)2元運(yùn)算符圃酵,它的2個(gè)運(yùn)算單元是值1和2柳畔。


賦值運(yùn)算符(Assignment Operator)

? ? 賦值運(yùn)算符(a = b)用來(lái)使用b的值初始化或者更新a的值。

? ??????let b = 10

????????var a = 5

????????a = b

????????// a 現(xiàn)在等于 10

? ? 如果賦值運(yùn)算符右邊是一個(gè)包含了多個(gè)值的元組郭赐,它的元素可以通過(guò)一次操作分出多個(gè)常量或者變量薪韩。

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

? ? 和C語(yǔ)言以及OC中不一樣,Swift中的賦值運(yùn)算符本身不會(huì)有返回值,所以下面的語(yǔ)句是無(wú)效的:

? ??????if x = y {?

????????? ? // 無(wú)效, 因?yàn)?x = y 沒(méi)有返回值.

????????}

? ? 這種特性可以防止賦值運(yùn)算符和相等比較運(yùn)算符(==)之間的誤用俘陷。通過(guò)是if x = y 無(wú)效罗捎,Swift可以防止在你的代碼中出現(xiàn)錯(cuò)誤。


術(shù)數(shù)運(yùn)算符(Arithmetic Operators)

? ? Swift為所有數(shù)字類型支持了4個(gè)基本的術(shù)數(shù)運(yùn)算符:

? ??????加法運(yùn)算符(+)? ??1 + 2 ?????// 3

? ? ? ? 減法運(yùn)算符(-)?? ??5 - 3 ????// 2

? ? ? ? 乘法運(yùn)算符(*)? ? ?2 * 3 ????// 6

? ? ? ? 除法運(yùn)算符(/) ? ?? 10.0 / 2.5 ????// 4.0

? ? 和C語(yǔ)言和OC中的術(shù)數(shù)運(yùn)算運(yùn)算符不一樣拉盾,Swift中的術(shù)數(shù)運(yùn)算符默認(rèn)不允許值溢出桨菜。可以使用Swift中值溢出運(yùn)算符來(lái)選擇值溢出的行為捉偏。

? ? 加法運(yùn)算符也要支持字符串的連接:

? ??????“hello, " + "world" ???? // 等于 "hello, world”

? 取余運(yùn)算符(Remainder Operator)

? ? 取余運(yùn)算符(a % b)計(jì)算出a里面可以包含多少個(gè)b,然后返回剩下的值,也就是余數(shù)雷激。

NOTE:取余運(yùn)算符(%)在其他語(yǔ)言中也被稱為模運(yùn)算符。然而嚴(yán)格來(lái)說(shuō),它是一個(gè)取余操作而不是取模操作告私。

? ? 9里面有2個(gè)4,所以余數(shù)是1屎暇。在Swift中,可以寫成: 9 % 4

? ? 取余運(yùn)算符使用下面的等式并且返回余數(shù)作為輸出驻粟,來(lái)決定 a % b 的結(jié)果:

? ??????a = (b x someMultiplier) + remainder

? ? 其中someMultipliera中可以有的最大的b的個(gè)數(shù)根悼,把9和4代入這個(gè)等式:

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

? ? 計(jì)算負(fù)數(shù)的時(shí)候使用的是同樣的計(jì)算公式:

? ? ? ? -9 % 4?? ??// -1?

? ? 把-94插入到上述的等式中:

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

? ? 可以得到余數(shù)的值是-1

? ? 在公式中負(fù)數(shù)?b 的符號(hào)會(huì)被忽略。這就意味著 a % ba % -b 的結(jié)果總是一樣的蜀撑。

一元減法運(yùn)算符(-)

? ? 數(shù)值可以使用前綴(-)挤巡,也就是一元減法運(yùn)算符:

? ??????let three = 3

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

????????let plusThree = -minusThree ? // 3

? ? 一元減法運(yùn)算符需要直接添加在需要操作的值前面,不需要有空格酷麦。

一元加法運(yùn)算符(+)

? ? 一元加法運(yùn)算符直接返回它操作的值矿卑,不做任何改變:

????????let minusSix = -6

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

? ? 雖然一元加法運(yùn)算符并不做任何事情,但是你可以在一些使用了一元減法運(yùn)算符的代碼中使用一元加法運(yùn)算符來(lái)保持代碼的對(duì)稱沃饶。

符合賦值運(yùn)算符(Compound Assignment Operators)

????和C語(yǔ)言一樣母廷,Swift提供了混合賦值運(yùn)算符,也就是賦值運(yùn)算符和其他運(yùn)算符組合使用糊肤。一個(gè)例子就是加法混合運(yùn)算符(+=):

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

????表達(dá)式?a += 2 a = a + 2 的簡(jiǎn)寫琴昆。為了更高的效率,加法運(yùn)算符和復(fù)制運(yùn)算符被組合在成一個(gè)運(yùn)算符馆揉,一次執(zhí)行了2個(gè)任務(wù)业舍。

NOTE:混合運(yùn)算符沒(méi)有返回值,比如升酣, let b = a += 2 是不對(duì)的舷暮。

比較運(yùn)算符

? ? Swift提供了標(biāo)準(zhǔn)C語(yǔ)言所有的比較運(yùn)算符:

? ? ? ? 等于?(a == b)? ? ? ?? ? ? ? ? ? ??不等于 (a != b)

? ? ? ? 大于 (a > b)?? ???????????????? ? ? 小于 (a < b)

? ? ? ? 大于等于 to (a >= b)? ? ? ? ?小于等于 (a <= b)

NOTE:Swift還提供了2個(gè)恒等運(yùn)算符(===和!==),可以用來(lái)測(cè)試2個(gè)對(duì)象的引用是不是引用于同一個(gè)對(duì)象的實(shí)例噩茄。

? ? 每一個(gè)比較運(yùn)算符返回一個(gè)布爾值來(lái)表明表達(dá)式是不是成立下面。

? ? 比較運(yùn)算符通常會(huì)用在條件語(yǔ)句中,比如if語(yǔ)句:

? ??????let name = "world"

????????if name == "world" {

????????? ? print("hello, world")

????????} else {

????????? ? print("I'm sorry \(name), but I don't recognize you")

????????}

????????// 打印 "hello, world", because name 等于 "world"

? ? 如果2個(gè)元組有相同的類型巢墅,也可以用比較運(yùn)算符比較诸狭。元組從左至右進(jìn)行比較券膀,一次比較一個(gè)值剿吻,直到比較結(jié)果不相等渣蜗。兩個(gè)對(duì)應(yīng)的值的比較,會(huì)決定整個(gè)元祖的比較的結(jié)果会涎。如果所有的元素都相等叉庐,那么元祖就是相等的舒帮,比如:

? ??????(1, "zebra") < (2, "apple") // true 因?yàn)?1 小于 2 ,后面的不比較

????????(3, "apple") < (3, "bird")? ? // true ?因?yàn)? 等于 3, "apple" 小于 "bird"

????????(4, "dog") == (4, "dog")? ? ? // true 因?yàn)?4 等于 4, and "dog" 等于 "dog”

? ? 上面的例子中,可以看見(jiàn)第一行從左往右進(jìn)行比較陡叠,因?yàn)?小于2玩郊,元組(1, "zebra")就被認(rèn)為小于元組(2, "apple"),無(wú)論元組中的其他值是什么枉阵。不會(huì)去考慮"zebra"并不小于"apple",因?yàn)榈谝粋€(gè)元素的的比較已經(jīng)決定了比較結(jié)果译红。然而,當(dāng)?shù)谝粋€(gè)元素比較結(jié)果相等的話兴溜,第二個(gè)元素就會(huì)被拿來(lái)比較侦厚,第二行和第三行就是這樣子做的。

? ? 只有在運(yùn)算符適用于元祖的每一個(gè)元素拙徽,元組才可以比較刨沦。比如下面的例子,可以比較 (String, Int)類型的元組膘怕,因?yàn)镾tring和Int都可以用 < 運(yùn)算符比較想诅。相對(duì)的,(String, Bool)類型的元組就不可以用 < 運(yùn)算符比較岛心,因?yàn)椴紶栔挡豢梢允褂?lt; 運(yùn)算符来破。

? ??????("blue", -1) < ("purple", 1) ?// OK, evaluates to true

????????("blue", false) < ("purple", true)? // 錯(cuò)誤,小于運(yùn)算符不適用于布爾值

NOTE:Swift標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)的元祖比較符只支持元素個(gè)數(shù)小于7個(gè)的元素。如果希望比較7個(gè)或者更多的元素的元組鹉梨,你需要自己實(shí)現(xiàn)比較運(yùn)算符讳癌。

三元條件運(yùn)算符(Ternary Conditional Operator)

? ??三元條件運(yùn)算符是一個(gè)包括了三個(gè)部分的特殊的元素的特殊的運(yùn)算符,就像這樣:?question ? answer1 : answer2

? ? 這是一種簡(jiǎn)潔代碼的方式存皂,它根據(jù)question的結(jié)果去決定是執(zhí)行answer1還是answer2,如果question的結(jié)果是true逢艘,會(huì)執(zhí)行并返回answer1的返回值旦袋,如果question的結(jié)果是false,會(huì)執(zhí)行并返回answer2的返回值它改。

?? ?三元條件運(yùn)算符是下面代碼的簡(jiǎn)寫:

????????if question {

????????? ? answer1

????????} else {

????????? ? answer2

????????}

? ? 在有2個(gè)表達(dá)式需要考慮的情況下疤孕,三木運(yùn)算提供了非常有效的簡(jiǎn)寫方式。然而央拖,請(qǐng)謹(jǐn)慎使用三木運(yùn)算祭阀,它很簡(jiǎn)潔鹉戚,但是過(guò)度使用付出的代價(jià)是難以閱讀。在一些混合語(yǔ)句中盡量避免使用三木運(yùn)算专控。

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

????空合運(yùn)算符(a ?? b)抹凳,如果可選值a有值,解包a并且返回a解包后的值,如果a沒(méi)有值,返回默認(rèn)值b伦腐。表達(dá)式中的a是一個(gè)可選值赢底,ba解包后的值的類型一樣。

? ? 空合運(yùn)算符下面代碼的簡(jiǎn)寫:

? ? ? ? a ?!= ?nil ? a! : b ? // (?a ?!= ?nil)中? != 是一個(gè)整體, ?而不是 a柏蘑!是一個(gè)整體P叶场!

? ? 上面的代碼使用了三目運(yùn)算符和強(qiáng)制解包去訪問(wèn)a中包含的值,當(dāng)a是nil的時(shí)候就返回b咳焚∏⑺穑空合運(yùn)算符以一種優(yōu)雅的方式,使得條件判斷和解包的操作可以用更精簡(jiǎn)和易讀的形式組合在了一起革半。

NOTE:如果a的值不是nil碑定,b的值不會(huì)被求值。也就是所謂的短路求值督惰。

? ? 下面的例子使用空合運(yùn)算符在默認(rèn)的顏色和用戶定義的顏色之間做選擇:

? ??????let defaultColorName = "red"

????????var userDefinedColorName: String?? // 默認(rèn)是nil

????????var colorNameToUse = userDefinedColorName ?? defaultColorName

????????// userDefinedColorName is nil, 所以使用默認(rèn)值?defaultColorName ?"red"

? ? 變量userDefinedColorName被定義為可選的String類型不傅,默認(rèn)是nil。因?yàn)?b>userDefinedColorName是可選值赏胚,所以可以在考慮它的值的時(shí)候使用空合運(yùn)算访娶。上面的例子中,空合運(yùn)算是為了決定變量colorNameToUse的初始值觉阅,因?yàn)?b>userDefinedColorName是nil崖疤,表示式userDefinedColorName ?? defaultColorName返回defaultColorName的值,也就是"red"典勇。

? ? 如果給可選變量userDefinedColorName賦予一個(gè)非空的值劫哼,然后再執(zhí)行空合運(yùn)算,將不會(huì)返回默認(rèn)值割笙,而是返回userDefinedColorName中包含的值权烧。

? ??????userDefinedColorName = "green"

????????colorNameToUse = userDefinedColorName ?? defaultColorName

????????// userDefinedColorName 不是 nil, 所以colorNameToUse現(xiàn)在是"green"

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市伤溉,隨后出現(xiàn)的幾起案子般码,更是在濱河造成了極大的恐慌,老刑警劉巖乱顾,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件板祝,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡走净,警方通過(guò)查閱死者的電腦和手機(jī)券时,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門孤里,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人橘洞,你說(shuō)我怎么就攤上這事捌袜。” “怎么了震檩?”我有些...
    開(kāi)封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵琢蛤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我抛虏,道長(zhǎng)博其,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任迂猴,我火速辦了婚禮慕淡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沸毁。我一直安慰自己峰髓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布息尺。 她就那樣靜靜地躺著携兵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪搂誉。 梳的紋絲不亂的頭發(fā)上徐紧,一...
    開(kāi)封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音炭懊,去河邊找鬼并级。 笑死,一個(gè)胖子當(dāng)著我的面吹牛侮腹,可吹牛的內(nèi)容都是我干的嘲碧。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼父阻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼愈涩!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起加矛,我...
    開(kāi)封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤钠署,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后荒椭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舰蟆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年趣惠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狸棍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡味悄,死狀恐怖草戈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情侍瑟,我是刑警寧澤唐片,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站涨颜,受9級(jí)特大地震影響费韭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜庭瑰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一星持、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弹灭,春花似錦督暂、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至捡鱼,卻和暖如春八回,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背堰汉。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工辽社, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人翘鸭。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓滴铅,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親就乓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汉匙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容