2基本运算符.docx
- 文档编号:5106914
- 上传时间:2022-12-13
- 格式:DOCX
- 页数:13
- 大小:36.18KB
2基本运算符.docx
《2基本运算符.docx》由会员分享,可在线阅读,更多相关《2基本运算符.docx(13页珍藏版)》请在冰豆网上搜索。
2基本运算符
TheSwiftProgrammingLanguage中文版
∙Abouttheauthor
∙QuestionsandIssues
∙EditandContribute
∙
∙Introduction
∙1. 欢迎使用Swift
o1.1. 关于Swift
o1.2. Swift初见
∙2. Swift教程
o2.1. 基础部分
o2.2. 基本运算符
o2.3. 字符串和字符
o2.4. 集合类型
o2.5. 控制流
o2.6. 函数
o2.7. 闭包
o2.8. 枚举
o2.9. 类和结构体
o2.10. 属性
o2.11. 方法
o2.12. 下标脚本
o2.13. 继承
o2.14. 构造过程
o2.15. 析构过程
o2.16. 自动引用计数
o2.17. 可选链
o2.18. 类型转换
o2.19. 嵌套类型
o2.20. 扩展
o2.21. 协议
o2.22. 泛型
o2.23. 高级操作符
∙3. 语言参考
o3.1. 关于语言参考
o3.2. 词法结构
o3.3. 类型
o3.4. 表达式
o3.5. 语句
o3.6. 声明
o3.7. 特性
o3.8. 模式
o3.9. 泛型参数
o3.10. 语法总结
∙
∙GeneratedusingGitBook
翻译:
xielingwang
校对:
Evilcome
基本运算符
本页包含内容:
∙术语
∙赋值运算符
∙数值运算符
∙组合赋值运算符(CompoundAssignmentOperators)
∙比较运算符
∙三元条件运算符(TernaryConditionalOperator)
∙区间运算符
∙逻辑运算符
运算符是检查、改变、合并值的特殊符号或短语。
例如,加号+将两个数相加(如leti=1+2)。
复杂些的运算例如逻辑与运算符&&(如ifenteredDoorCode&&passedRetinaScan),或让i值加1的便捷自增运算符++i等。
Swift支持大部分标准C语言的运算符,且改进许多特性来减少常规编码错误。
如:
赋值符(=)不返回值,以防止把想要判断相等运算符(==)的地方写成赋值符导致的错误。
数值运算符(+,-,*,/,%等)会检测并不允许值溢出,以此来避免保存变量时由于变量大于或小于其类型所能承载的范围时导致的异常结果。
当然允许你使用Swift的溢出运算符来实现溢出。
详情参见溢出运算符。
区别于C语言,在Swift中你可以对浮点数进行取余运算(%),Swift还提供了C语言没有的表达两数之间的值的区间运算符,(a..b和a...b),这方便我们表达一个区间内的数值。
本章节只描述了Swift中的基本运算符,高级运算符包含了高级运算符,及如何自定义运算符,及如何进行自定义类型的运算符重载。
术语
运算符有一元、二元和三元运算符。
∙一元运算符对单一操作对象操作(如-a)。
一元运算符分前置符和后置运算符,前置运算符需紧排操作对象之前(如!
b),后置运算符需紧跟操作对象之后(如i++)。
∙二元运算符操作两个操作对象(如2+3),是中置的,因为它们出现在两个操作对象之间。
∙三元运算符操作三个操作对象,和C语言一样,Swift只有一个三元运算符,就是三元条件运算符(a?
b:
c)。
受运算符影响的值叫操作数,在表达式1+2中,加号+是二元运算符,它的两个操作数是值1和2。
赋值运算符
赋值运算(a=b),表示用b的值来初始化或更新a的值:
letb=10
vara=5
a=b
//a现在等于10
如果赋值的右边是一个多元组,它的元素可以马上被分解多个变量或变量:
let(x,y)=(1,2)
//现在x等于1,y等于2
与C语言和Objective-C不同,Swift的赋值操作并不返回任何值。
所以以下代码是错误的:
ifx=y{
//此句错误,因为x=y并不返回任何值
}
这个特性使你无法把(==)错写成(=),由于ifx=y是错误代码,Swift从底层帮你避免了这些错误代码。
数值运算
Swift中所有数值类型都支持了基本的四则运算:
∙加法(+)
∙减法(-)
∙乘法(*)
∙除法(/)
1+2//等于3
5-3//等于2
2*3//等于6
10.0/2.5//等于4.0
与C语言和Objective-C不同的是,Swift默认不允许在数值运算中出现溢出情况。
但你可以使用Swift的溢出运算符来达到你有目的的溢出(如a&+b)。
详情参见溢出运算符。
加法运算符也可用于String的拼接:
"hello,"+"world"//等于"hello,world"
两个Character值或一个String和一个Character值,相加会生成一个新的String值:
letdog:
Character="d"
letcow:
Character="c"
letdogCow=dog+cow
//译者注:
原来的引号内是很可爱的小狗和小牛,但winos下不支持表情字符,所以改成了普通字符
//dogCow现在是"dc"
详情参见字符,字符串的拼接。
求余运算
求余运算(a%b)是计算b的多少倍刚刚好可以容入a,返回多出来的那部分(余数)。
注意:
求余运算(%)在其他语言也叫取模运算。
然而严格说来,我们看该运算符对负数的操作结果,"求余"比"取模"更合适些。
我们来谈谈取余是怎么回事,计算9%4,你先计算出4的多少倍会刚好可以容入9中:
2倍,非常好,那余数是1(用橙色标出)
在Swift中这么来表达:
9%4//等于1
为了得到a%b的结果,%计算了以下等式,并输出余数作为结果:
a=(b×倍数)+余数
当倍数取最大值的时候,就会刚好可以容入a中。
把9和4代入等式中,我们得1:
9=(4×2)+1
同样的方法,我来们计算 -9%4:
-9%4//等于-1
把-9和4代入等式,-2是取到的最大整数:
-9=(4×-2)+-1
余数是-1。
在对负数b求余时,b的符号会被忽略。
这意味着 a%b 和 a%-b的结果是相同的。
浮点数求余计算
不同于C语言和Objective-C,Swift中是可以对浮点数进行求余的。
8%2.5//等于0.5
这个例子中,8除于2.5等于3余0.5,所以结果是一个Double值0.5。
自增和自增运算
和C语言一样,Swift也提供了方便对变量本身加1或减1的自增(++)和自减(--)的运算符。
其操作对象可以是整形和浮点型。
vari=0
++i//现在i=1
每调用一次++i,i的值就会加1。
实际上,++i是i=i+1的简写,而--i是i=i-1的简写。
++和--既是前置又是后置运算。
++i,i++,--i和i--都是有效的写法。
我们需要注意的是这些运算符修改了i后有一个返回值。
如果你只想修改i的值,那你就可以忽略这个返回值。
但如果你想使用返回值,你就需要留意前置和后置操作的返回值是不同的。
∙当++前置的时候,先自増再返回。
∙当++后置的时候,先返回再自增。
例如:
vara=0
letb=++a//a和b现在都是1
letc=a++//a现在2,但c是a自增前的值1
上述例子,letb=++a先把a加1了再返回a的值。
所以a和b都是新值1。
而letc=a++,是先返回了a的值,然后a才加1。
所以c得到了a的旧值1,而a加1后变成2。
除非你需要使用i++的特性,不然推荐你使用++i和--i,因为先修改后返回这样的行为更符合我们的逻辑。
一元负号
数值的正负号可以使用前缀-(即一元负号)来切换:
letthree=3
letminusThree=-three//minusThree等于-3
letplusThree=-minusThree//plusThree等于3,或"负负3"
一元负号(-)写在操作数之前,中间没有空格。
一元正号
一元正号(+)不做任何改变地返回操作数的值。
letminusSix=-6
letalsoMinusSix=+minusSix//alsoMinusSix等于-6
虽然一元+做无用功,但当你在使用一元负号来表达负数时,你可以使用一元正号来表达正数,如此你的代码会具有对称美。
复合赋值(CompoundAssignmentOperators)
如同强大的C语言,Swift也提供把其他运算符和赋值运算(=)组合的复合赋值运算符,加赋运算(+=)是其中一个例子:
vara=1
a+=2//a现在是3
表达式a+=2是a=a+2的简写,一个加赋运算就把加法和赋值两件事完成了。
注意:
复合赋值运算没有返回值,letb=a+=2这类代码是错误。
这不同于上面提到的自增和自减运算符。
在表达式章节里有复合运算符的完整列表。
比较运算
所有标准C语言中的比较运算都可以在Swift中使用。
∙等于(a==b)
∙不等于(a!
=b)
∙大于(a>b)
∙小于(a
∙大于等于(a>=b)
∙小于等于(a<=b)
注意:
Swift也提供恒等===和不恒等!
==这两个比较符来判断两个对象是否引用同一个对象实例。
更多细节在类与结构。
每个比较运算都返回了一个标识表达式是否成立的布尔值:
1==1//true,因为1等于1
2!
=1//true,因为2不等于1
2>1//true,因为2大于1
1<2//true,因为1小于2
1>=1//true,因为1大于等于1
2<=1//false,因为2并不小于等于1
比较运算多用于条件语句,如if条件:
letname="world"
ifname=="world"{
println("hello,world")
}else{
println("I'msorry\(name),butIdon'trecognizeyou")
}
//输出"hello,world",因为`name`就是等于"world"
关于if语句,请看控制流。
三元条件运算(TernaryConditionalOperator)
三元条件运算的特殊在于它是有三个操作数的运算符,它的原型是 问题?
答案1:
答案2。
它简洁地表达根据问题成立与否作出二选一的操作。
如果问题成立,返回答案1的结果;如果不成立,返回答案2的结果。
使用三元条件运算简化了以下代码:
ifquestion:
{
answer1
}else{
answer2
}
这里有个计算表格行高的例子。
如果有表头,那行高应比内容高度要高出50像素;如果没有表头,只需高出20像素。
letcontentHeight=40
lethasHeader=true
letrowHeight=contentHeight+(hasHeader?
50:
20)
//rowHeight现在是90
这样写会比下面的代码简洁:
letcontentHeight=40
lethasHeader=true
varrowHeight=contentHeight
ifhasHeader{
rowHeight=rowHeight+50
}else{
rowHeight=rowHeight+20
}
//rowHeight现在是90
第一段代码例子使用了三元条件运算,所以一行代码就能让我们得到正确答案。
这比第二段代码简洁得多,无需将rowHeight定义成变量,因为它的值无需在if语句中改变。
三元条件运算提供有效率且便捷的方式来表达二选一的选择。
需要注意的事,过度使用三元条件运算就会由简洁的代码变成难懂的代码。
我们应避免在一个组合语句使用多个三元条件运算符。
区间运算符
Swift提供了两个方便表达一个区间的值的运算符。
闭区间运算符
闭区间运算符(a...b)定义一个包含从a到b(包括a和b)的所有值的区间。
闭区间运算符在迭代一个区间的所有值时是非常有用的,如在for-in循环中:
forindexin1...5{
println("\(index)*5=\(index*5)")
}
//1*5=5
//2*5=10
//3*5=15
//4*5=20
//5*5=25
关于for-in,请看控制流。
半闭区间
半闭区间(a..b)定义一个从a到b但不包括b的区间。
之所以称为半闭区间,是因为该区间包含第一个值而不包括最后的值。
半闭区间的实用性在于当你使用一个0始的列表(如数组)时,非常方便地从0数到列表的长度。
letnames=["Anna","Alex","Brian","Jack"]
letcount=names.count
foriin0..count{
println("第\(i+1)个人叫\(names[i])")
}
//第1个人叫Anna
//第2个人叫Alex
//第3个人叫Brian
//第4个人叫Jack
数组有4个元素,但0..count只数到3(最后一个元素的下标),因为它是半闭区间。
关于数组,请查阅数组。
逻辑运算
逻辑运算的操作对象是逻辑布尔值。
Swift支持基于C语言的三个标准逻辑运算。
∙逻辑非(!
a)
∙逻辑与(a&&b)
∙逻辑或(a||b)
逻辑非
逻辑非运算(!
a)对一个布尔值取反,使得true变false,false变true。
它是一个前置运算符,需出现在操作数之前,且不加空格。
读作非a,然后我们看以下例子:
letallowedEntry=false
if!
allowedEntry{
println("ACCESSDENIED")
}
//输出"ACCESSDENIED"
if!
allowedEntry语句可以读作"如果非alowedentry。
",接下一行代码只有在如果"非allowentry"为true,即allowEntry为false时被执行。
在示例代码中,小心地选择布尔常量或变量有助于代码的可读性,并且避免使用双重逻辑非运算,或混乱的逻辑语句。
逻辑与
逻辑与(a&&b)表达了只有a和b的值都为true时,整个表达式的值才会是true。
只要任意一个值为false,整个表达式的值就为false。
事实上,如果第一个值为false,那么是不去计算第二个值的,因为它已经不可能影响整个表达式的结果了。
这被称做"短路计算(short-circuitevaluation)"。
以下例子,只有两个Bool值都为true值的时候才允许进入:
letenteredDoorCode=true
letpassedRetinaScan=false
ifenteredDoorCode&&passedRetinaScan{
println("Welcome!
")
}else{
println("ACCESSDENIED")
}
//输出"ACCESSDENIED"
逻辑或
逻辑或(a||b)是一个由两个连续的|组成的中置运算符。
它表示了两个逻辑表达式的其中一个为true,整个表达式就为true。
同逻辑与运算类似,逻辑或也是"短路计算"的,当左端的表达式为true时,将不计算右边的表达式了,因为它不可能改变整个表达式的值了。
以下示例代码中,第一个布尔值(hasDoorKey)为false,但第二个值(knowsOverridePassword)为true,所以整个表达是true,于是允许进入:
lethasDoorKey=false
letknowsOverridePassword=true
ifhasDoorKey||knowsOverridePassword{
println("Welcome!
")
}else{
println("ACCESSDENIED")
}
//输出"Welcome!
"
组合逻辑
我们可以组合多个逻辑运算来表达一个复合逻辑:
ifenteredDoorCode&&passedRetinaScan||hasDoorKey||knowsOverridePassword{
println("Welcome!
")
}else{
println("ACCESSDENIED")
}
//输出"Welcome!
"
这个例子使用了含多个&&和||的复合逻辑。
但无论怎样,&&和||始终只能操作两个值。
所以这实际是三个简单逻辑连续操作的结果。
我们来解读一下:
如果我们输入了正确的密码并通过了视网膜扫描;或者我们有一把有效的钥匙;又或者我们知道紧急情况下重置的密码,我们就能把门打开进入。
前两种情况,我们都不满足,所以前两个简单逻辑的结果是false,但是我们是知道紧急情况下重置的密码的,所以整个复杂表达式的值还是true。
使用括号来明确优先级
为了一个复杂表达式更容易读懂,在合适的地方使用括号来明确优先级是很有效的,虽然它并非必要的。
在上个关于门的权限的例子中,我们给第一个部分加个括号,使用它看起来逻辑更明确:
if(enteredDoorCode&&passedRetinaScan)||hasDoorKey||knowsOverridePassword{
println("Welcome!
")
}else{
println("ACCESSDENIED")
}
//输出"Welcome!
"
这括号使得前两个值被看成整个逻辑表达中独立的一个部分。
虽然有括号和没括号的输出结果是一样的,但对于读代码的人来说有括号的代码更清晰。
可读性比简洁性更重要,请在可以让你代码变清晰地地方加个括号吧!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基本 运算