級別: ★☆☆☆☆
標(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 += 2
是a = 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)算符比較String
和Int
值。相反火欧,兩個類型(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é)果
}
- 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
梦碗;如果a
為nil
,則返回默認(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)
定義從a
到b
的范圍阵漏,并包括值a
和b
并且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
定義從a
到b
的范圍,但不包括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
邏輯值為true
和false
窍侧。
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(一)