Swift 5.1 (2) - 運(yùn)算符

級別: ★☆☆☆☆
標(biāo)簽:「iOS」「Swift 5.1」「運(yùn)算符」
作者: 沐靈洛
審校: QiShare團(tuán)隊(duì)


運(yùn)算符的術(shù)語:操作符分為一元,二元蔼卡,三元皮仁。

  • 一元運(yùn)算符主要操作一個單一的目標(biāo)(比如:-a)。一元前綴運(yùn)算符可以直接出現(xiàn)在它們的目標(biāo)前面(比如:!b)菲宴,一元后綴運(yùn)算符直接出現(xiàn)在它們目標(biāo)之后(比如:c!)。
  • 二元運(yùn)算符在兩個目標(biāo)(例如2 + 3)上運(yùn)行趋急,并且是中綴喝峦,因?yàn)樗鼈兂霈F(xiàn)在兩個目標(biāo)之間。
  • 三元運(yùn)算符在三個目標(biāo)上進(jìn)行運(yùn)算呜达。與C一樣谣蠢,Swift只有一個三元運(yùn)算符,即三元條件運(yùn)算符(a查近?b:c)

賦值運(yùn)算符: 賦值運(yùn)算符(a = b)使用b值初始化或更新a的值眉踱。

let b = 10
var a = 5
a = b //a的值變?yōu)榱?0

如果賦值的右側(cè)是具有多個值的元組,則元組的元素可以一次分解為多個常量或變量霜威。

let (x, y) = (1, 2)//!< x = 1 , y = 2

與C和Objective-C中的賦值運(yùn)算符不同谈喳,Swift中的賦值運(yùn)算符本身不返回值。以下聲明無效

 if x = y {//!< '='運(yùn)算符在swift中沒有返回值戈泼,所以此處這樣寫是無效的婿禽,同時會報錯。
        }

此功能可防止在實(shí)際使用等于運(yùn)算符==時意外使用賦值運(yùn)算符=大猛,通過使x = y無效扭倾,Swift可以幫助我們避免代碼中的這類錯誤。

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

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

與C和Objective-C中的算術(shù)運(yùn)算符不同挽绩,Swift算術(shù)運(yùn)算符默認(rèn)情況下不允許值溢出膛壹。我們可以通過使用Swift的溢出運(yùn)算符(例如&+ b)來選擇值溢出行為。請參閱溢出運(yùn)算符
字符串連接也支持加法運(yùn)算符:

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

求余運(yùn)算符:余數(shù)運(yùn)算符(a%b)計算出a中將包含多少個b唉堪,并返回剩余的值(稱為余數(shù))

9 % 4    // equals 1
-9 % 4   // equals -1

一元-+運(yùn)算符:可以使用-(稱為一元減運(yùn)算符)直接添加于運(yùn)行的值之前模聋,沒有任何空格,切換數(shù)值的符號巨坊。使用+(稱為一元加運(yùn)算符)直接添加于運(yùn)行的值之前撬槽,沒有任何空格,一元加運(yùn)算符+只返回它操作的值趾撵,沒有任何變化侄柔。
一元減運(yùn)算符

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

一元加運(yùn)算符

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

即使一元加運(yùn)算符實(shí)際上沒有做任何事情共啃,但是當(dāng)使用一元減運(yùn)算符作為負(fù)數(shù)時蝗罗,我們可以使用它來為代碼提供正數(shù)的對稱性逾礁。
復(fù)合賦值運(yùn)算符::與C一樣滞造,Swift提供了將賦值=與另一個操作符相結(jié)合的復(fù)合賦值運(yùn)算符椅亚。比如加法賦值運(yùn)算符+ =

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

表達(dá)式a += 2a = a + 2的簡寫披粟。實(shí)際上镊靴,加法和賦值操作符被組合成一個同時執(zhí)行兩個任務(wù)的運(yùn)算符盾致。
需要注意的是:復(fù)合賦值運(yùn)算符不返回值照弥。例如:不能寫let b = a += 2言津。
比較運(yùn)算符: Swift支持所有標(biāo)準(zhǔn)C比較運(yùn)算符攻人。

  • 等于 == , 如:(a == b)
  • 不等于!=, 如: (a != b)
  • 大于>, 如: (a > b)
  • 小于<, 如: (a < b)
  • 大于等于>=, 如: (a >= b)
  • 小于等于!=, 如: (a <= b)
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

比較運(yùn)算符通常用于條件語句,例如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".

比較元組:如果它們具有相同的類型和相同的數(shù)值悬槽,則可以比較兩個元組怀吻。元組從左到右進(jìn)行比較,一次一個值初婆,直到比較發(fā)現(xiàn)兩個不相等的值蓬坡。比較這兩個值,并且該比較的結(jié)果確定元組比較的總體結(jié)果磅叛。如果所有元素都相等屑咳,則元組本身是相等的。即:在可以比較的前提下弊琴,只要按順序比較找到兩個元組中不相同的兩個值兆龙,則進(jìn)行比較并且返回,作為元組的比較結(jié)果敲董,后面的值將不再進(jìn)行比較例如:

(1, "zebra") < (2, "apple")   //返回 true 因?yàn)? 小于2  "zebra" 和 "apple" 將不比較:“ zebra”不小于“apple”并不重要详瑞,因?yàn)楸容^已經(jīng)由元組的第一個元素決定,當(dāng)元組的第一個元素相同時臣缀,它們的第二個元素會被比較坝橡。
但是,當(dāng)元組的第一個元素相同時精置,它們的第二個元素會被比較计寇,下面就是這種情況
(3, "apple") < (3, "bird")    // 返回 true 因?yàn)?3 等于 3, "apple"小于"bird"
(4, "dog") == (4, "dog")      //返回 true 因?yàn)?4 等于 4, "dog" 等于"dog"

另:只有當(dāng)給定運(yùn)算符可以應(yīng)用于相應(yīng)元組中的每個值時,才能將元組運(yùn)用給定運(yùn)算符進(jìn)行比較脂倦。
例如番宁,如下面的代碼所示,您可以比較兩個類型(String赖阻,Int)的元組蝶押,因?yàn)榭梢允褂?code><運(yùn)算符比較StringInt值。相反火欧,兩個類型(String棋电,Bool)的元組不能與<運(yùn)算符進(jìn)行比較茎截,因?yàn)?code><運(yùn)算符不能應(yīng)用于Bool值。

if ("blue", -1) < ("purple", 1)  {
    print("結(jié)果成立赶盔,返回了true")
}
if ("blue", false) < ("purple", true) {//!< 編譯器直接會報錯
    print("Binary operator '<' cannot be applied to two '(String, Bool)' operands")
}

Swift標(biāo)準(zhǔn)庫包含的比較元組時企锌,只限于元組少于7個元素。要將元組與七個或更多元素進(jìn)行比較于未,我們必須自己實(shí)現(xiàn)比較運(yùn)算符撕攒。

另外:Swift還提供了兩個標(biāo)識運(yùn)算符(===和!==),用于測試兩個對象引用是否都引用同一個對象實(shí)例
身份運(yùn)算符: 因?yàn)轭愂且妙愋秃嫫郑远鄠€常量和變量可能引用同一個類的單個實(shí)例抖坪。(對于結(jié)構(gòu)體和枚舉,情況也是如此闷叉,因?yàn)樗鼈冊诜峙浣o常量或變量或傳遞給函數(shù)時總是被復(fù)制)Swift 提供了兩個身份運(yùn)算符來找出兩個常量或變量是否完全引用類的相同實(shí)例柳击。

  • 相同 (===)
  • 不相同 (!==)

注意:相同===并不意味著等于=====意味著類類型(class type)的兩個常量或變量引用了完全相同的類實(shí)例片习。等于意味著兩個實(shí)例在值上被認(rèn)為是相等的。
1.obj1和obj2常量都是類類型蹬叭,兩者引用了不相同的類的實(shí)例對象

let obj1 = UIView.init()
let obj2 = UIView.init()
let (x,y) = (obj1,obj2)
if x === y {
   print("obj1和obj2常量都是類類型藕咏,并且兩者引用了完全相同的類的實(shí)例對象")
} else{
   print("obj1和obj2常量都是類類型,兩者引用了不相同的類的實(shí)例對象")//!< 打印結(jié)果
}
  1. obj1和obj2常量都是類類型秽五,并且兩者引用了完全相同的類的實(shí)例對象
let obj1 = UIView.init()
let obj2 = obj1
let (x,y) = (obj1,obj2)
if x !== y {
    print("obj1和obj2常量都是類類型孽查,兩者引用了不相同的類的實(shí)例對象")
} else{
    print("obj1和obj2常量都是類類型,并且兩者引用了完全相同的類的實(shí)例對象")//!< 打印結(jié)果
}

三元條件運(yùn)算符:三元條件運(yùn)算符是一個特殊的運(yùn)算符坦喘,有三個部分盲再,使用用形式:question ? answer1 : answer2。如果問題為真瓣铣,則返回answer1答朋;否則返回answer2。
三元條件運(yùn)算符是以下代碼的簡寫:

if question {
    answer1
} else {
    answer2
}

可Nil合并(Nil-Coalescing)運(yùn)算符:nil-coalescing運(yùn)算符??解包一個可選的a使用形式:a ?? b棠笑。解讀為:解包可選a梦碗;如果anil,則返回默認(rèn)值b蓖救,否則返回a洪规。表達(dá)式中a始終是可選類型。并且b必須與a的類型匹配循捺。
nil-coalescing運(yùn)算符是下面代碼的簡寫:

a! =  nil  ?  a!  :  b //<! 使用三元條件運(yùn)算符和強(qiáng)制解包(aU独)來訪問包含在a不是nil時的值,否則返回b

上面的代碼使用三元條件運(yùn)算符和強(qiáng)制解包a从橘!來訪問包含在可選的a中的值念赶,若不是nil時础钠,則不去管b的值,并返回a中的值晶乔,否則返回b珍坊。

let defaultColorName = "red"
var userDefinedColorName: String?   // defaults to nil
var colorNameToUse = userDefinedColorName ?? defaultColorName

返回運(yùn)算符: Swift包含多個范圍運(yùn)算符。
1.封閉范圍運(yùn)算符(Close Range Operator):封閉范圍運(yùn)算符...正罢,使用形式(a ... b)定義從ab的范圍阵漏,并包括值ab并且a的值不得大于b
當(dāng)我們希望在所有值的全部范圍內(nèi)進(jìn)行遍歷時翻具,閉合范圍運(yùn)算符非常有用履怯,例如使用for-in循環(huán):

for item in 1...8 {
    print(item)//!< 打印 12345678
}

2.半開范圍運(yùn)算符(Half-Open Range Operator):半開范圍運(yùn)算符..<使用形式:a .. <b定義從ab的范圍,但不包括b裆泳,它被認(rèn)為是半開放的叹洲,因?yàn)橹话牡谝粋€值卻沒有它的最終值。與封閉范圍運(yùn)算符一樣工禾,a的值不得大于b运提。如果a的值等于b,則最終有效范圍將為空闻葵。
當(dāng)我們遍歷基于零的列表(如數(shù)組)民泵,因?yàn)閿?shù)組的長度需要計算,此時根據(jù)定義槽畔,使用半開范圍運(yùn)算符是最合適的栈妆。

/*打印結(jié)果:
 索引:0,對應(yīng)字符串:i
 索引:1,對應(yīng)字符串:am
 索引:2,對應(yīng)字符串:zhangfei
*/
let array = ["i","am","zhangfei"]
for index in 0 ..< array.count { //!< 遍歷數(shù)組
    print("索引:\(index),對應(yīng)字符串:\(array[index])")
}
//直接輸出字符串,形式
let array = ["i","am","zhangfei"]
for str in array[0..<array.count] {
    print(str)
}

3.局部(單面/側(cè))范圍(One-Sided Ranges):封閉范圍運(yùn)算符(Close Range Operator)半開范圍運(yùn)算符(Half-Open Range Operator)的使用延伸。
封閉范圍運(yùn)算符有一個替代形式厢钧,用于使范圍在一個方向上盡可能繼續(xù)鳞尔。例如:一個數(shù)組從索引位置2到數(shù)組末尾的所有元素的范圍。這種情況下我們可以省略運(yùn)算符一側(cè)的值早直。具體使用:

let array = ["i","am","zhangfei"]
//直接輸出字符串 形式1
for str in array[...]{
    print(str)
}
//直接輸出字符串 形式2 此處`1`可以是數(shù)組范圍內(nèi)小于`array.count-1`的任意值
for str in array[1...] {
    print(str)
}
//直接輸出字符串 形式3 此處`(array.count-1)`可以是數(shù)組范圍內(nèi)大于0的任意值
for str in array[...(array.count-1)] {
    print(str)
}

半開放范圍操作符也具有單側(cè)形式寥假,僅使用其最終值編寫,最終值不是范圍的一部分霞扬,因?yàn)槭切∮?code><昧旨。具體使用

//直接輸出字符串 形式4 
for str in array[..<array.count] {
    print(str)
}

局部(單面/側(cè))范圍(One-Sided Ranges)可以在其他上下文中使用,而不僅僅在下標(biāo)中使用祥得。在需要遍歷的情況下不能忽略了單側(cè)范圍的第一個值兔沃,因?yàn)楸闅v需要清楚的知道應(yīng)該從哪里開始。我們卻可以使用忽略了最終值單側(cè)范圍级及,但是范圍可以無限期的繼續(xù)乒疏,所以需要確保為我們的循環(huán)添加顯式結(jié)束條件,我們還可以檢查單側(cè)范圍是否包含特定的值饮焦。具體示例如下:

let range = ...5
range.contains(7)   // false
range.contains(4)   // true
range.contains(-1)  // true

關(guān)于范圍可以無限期的繼續(xù)怕吴,所以需要確保為我們的循環(huán)添加顯式結(jié)束條件舉例如下:

let range =  0...
for i in range {//!< 代碼無限期的執(zhí)行
    print(i)
}

邏輯運(yùn)算符: 邏輯運(yùn)算符修改Boolean邏輯值為truefalse窍侧。
Swift支持基于C語言的三個標(biāo)準(zhǔn)邏輯運(yùn)算符。

  • 邏輯非 ! 如:!a
  • 邏輯與 &&如:a && b
  • 邏輯或 ||如:a || b

參考資料:
swift 5.1官方編程指南


推薦文章:
Swift 5.1(1) - 基礎(chǔ)
iOS UI狀態(tài)保存和恢復(fù)(三)
iOS UI狀態(tài)保存和恢復(fù)(二)
iOS UI狀態(tài)保存和恢復(fù)(一)
iOS 中精確定時的常用方法
Sign In With Apple(一)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末转绷,一起剝皮案震驚了整個濱河市伟件,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌议经,老刑警劉巖斧账,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異煞肾,居然都是意外死亡咧织,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門籍救,熙熙樓的掌柜王于貴愁眉苦臉地迎上來习绢,“玉大人,你說我怎么就攤上這事蝙昙∩撂眩” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵奇颠,是天一觀的道長败去。 經(jīng)常有香客問我,道長大刊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任三椿,我火速辦了婚禮缺菌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搜锰。我一直安慰自己伴郁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布蛋叼。 她就那樣靜靜地躺著焊傅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狈涮。 梳的紋絲不亂的頭發(fā)上狐胎,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機(jī)與錄音歌馍,去河邊找鬼握巢。 笑死,一個胖子當(dāng)著我的面吹牛松却,可吹牛的內(nèi)容都是我干的暴浦。 我是一名探鬼主播溅话,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼歌焦!你這毒婦竟也來了飞几?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤独撇,失蹤者是張志新(化名)和其女友劉穎屑墨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體券勺,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绪钥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了关炼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片程腹。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖儒拂,靈堂內(nèi)的尸體忽然破棺而出寸潦,到底是詐尸還是另有隱情,我是刑警寧澤社痛,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布见转,位于F島的核電站,受9級特大地震影響蒜哀,放射性物質(zhì)發(fā)生泄漏斩箫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一撵儿、第九天 我趴在偏房一處隱蔽的房頂上張望乘客。 院中可真熱鬧,春花似錦淀歇、人聲如沸易核。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牡直。三九已至,卻和暖如春纳决,著一層夾襖步出監(jiān)牢的瞬間碰逸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工阔加, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留花竞,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像约急,于是被迫代替她去往敵國和親零远。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

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