赋值和算术运算符
基本概念
- 一元运算符对一个目标进行操作。一元前缀运算符(如!b),一元后缀运算符(b!)
- 二元运算符对两个目标进行操作(比如a+b)同时因为它们出现在两个目标之间,所以是中缀
- 三元运算符操作三个目标。Swift语言也仅有一个三元运算符。三元t条件运算符(a ? b : c)
Swift运算符的改进
- Swift在支持C中的大多数标准运算符的同时也增加了一些排除常见代码错误的能力:
- 赋值符号(=)不会返回值,以防它被误用于符号(==)的意图上
- 算数符号(+,-,*,/,%以及其他)可以检测并阻止值溢出,以避免你在操作比储存类型允许的范围更大或者更小的数字时得到各种奇奇怪怪的结果
赋值运算符
- 赋值运算符将一个值赋给另外一个值
- 如果赋值符号右侧是拥有多个值得元组,它的元素将会一次性地拆分成常量或者变量
- Swift的赋值符号自身不会返回值
算数运算符 - 标准运算符
- 标准算术运算符+ - * /
- 加法运算符同时也支持String的拼接
- Swift算术运算符默认不允许值溢出
算术运算符 - 余数运算符
- 余数运算符(a%b)可以求出多少个b的倍数能够刚好放进a中并且返回剩下的值(就是我们所谓的余数)
- 当a是负数时也使用相同的方法来进行计算
- 当b为负数时它的正负号被忽略掉了。这意味着a%b与a%-b能够获得相同的答案
letc=9%4print(c) //1letd=9%-4print(d) //1lete=-9%4print(e) //-1
算术运算符 - 一元
- 数字值得正负号可以用前缀-来切换,我们称之为一元减号运算符
- 一元减号运算符(-)直接在要进行操作的值前边放置,不加任何空格
- 一元加号运算符(+)直接返回它操作的值,不会对其进行任何的修改
在Swift里如何处理算术结果溢出
溢出运算符
- 在默认情况下,当向一个整数赋超过它容量的值时,Swift会报错而不是生成一个无效的数,给我们操作过大或者小的数的时候提供额外的安全性
- 同时提供三个算数溢出运算符来让系统支持整数溢出运算:
- 溢出加法(&+)
- 溢出加法(&-)
- 溢出乘法(&*)
值溢出
- 数值可以出现向上溢出或向下溢出
- 溢出也会发生在有符号整型数值上
- 对于无符号与有符号整型数值来说,当出现上溢时,它们会从数值所能容纳的最大数变成最小的数。同样的,当发生下溢出时,它们会从所能容纳的最小数变成最大的数
为了Optional:合并空值运算符
合并空值运算符
- 合并空值运算符(a ?? b)如果可选项a有值则展开,如果没有值,是nil,则返回默认值b
- 表达式a必须是一个可选类型。表达式b必须与a的储存类型相同
- 实际上是三元运算符作用到Optional上的缩写( a != nil ? a! : b)
- 如果a的值是非空的,b的值将不会被考虑,也就是合并空值运算符是短路的
Swift新宠:区间运算符
闭区间运算符
- 闭区间运算符(a...b)定义了从a到b的一组范围,并且包含a和b。a的值不能大于b
半开区间运算符
- 半开区间运算符(a..
- 如同闭区间运算符,a的值也不能大于b,如果a与b的值相等,那返回的区间将会是空的
单侧区间
- 闭区间有另外一种形式来让区间朝一个方向尽可能的远,这种区间叫做单侧区间
- 半开区间运算符同样可以有单侧形式,只需要写它最终的值
- 比如说,一个包含数组所有元素的区间,从索引2到数组的结束。在这种情况下,你可以省略区间运算符一侧的值
- 单侧区间可以在其他上下文中使用,不仅仅是下标
- 不能遍历省略了第一个值的单侧区间,因为遍历根本不知道该从哪里开始。你可以遍历省略了最终值得单侧区间
字符串索引区间
- 字符串范围也可以使用区间运算符
倒序索引
- 通过reversed()方法,我们可以将一个正序循环变成逆序循环
Comparable区间
- 区间运算符可以作用在Comparable类型上,返回闭区间和半闭区间
强大的位运算符
位取反运算符
- 位取反运算符(~)是对所有位的数字进行取反操作
letnumber1: UInt8=255letnumber2=~number1print(number2) //0
位与运算符
- 位与运算符(&)可以对两个数的比特位进行合并。它会返回一个新的数,只有当这两个数都是1的时候才能返回1
位或运算符
- 位或运算符(|)可以对两个比特位进行比较,然后返回一个新的数,只要两个操作位任意一个为1时,那么对应的位数就为1
letnumber1: UInt8=255letnumber2=~number1print(number2) //0letnumber3=number1&number2letnumber4=number1|number2print(number3) print(number4) //0//255
位异或运算符
- 位异或运算符,或者说“互斥或”(^)可以对两个数的比特位进行比较。它返回一个新的数,当两个操作数的对应位不相同时,该数的对应位就为1
letnumber1: UInt8=255letnumber2=~number1print(number2) //0letnumber5=number1^number2print(number5) //255
位左移和右移运算符
- 位左移运算符(<<)和位右移运算符(>>)可以把所有位数的数字向左或向右移动一个确定的位数
- 位左移和右移具有给整数乘以或除以二的效果。将一个数左移一位相当于把这个数翻倍,将一个数右移一位相当于把这个数减半
letnumber6: Int8=8print(number6<<1) print(number6>>1) //16//4letnumber7: Int8=-8print(number7<<1) print(number7>>1) //-16//-4
无符号整数的位移操作
- 已经存在的比特位按指定的位数进行左移和右移
- 任何移动超出整型存储边界的位都会被丢弃
- 用0来填充向左或向右移动后产生的空白位
有符号整数的位移操作
- 有符号整数使用它的第一位(所谓的符号位)来表示这个整数是正数还是负数。符号位为0表示为正数,1表示为负数
- 其余的位数(所谓的数值位)存储了实际的值。有符号正整数和无符号数的存储方式是一样的,都是从0开始算起。
- 但是负数的存储方式略有不同。它存储的是2的n次方减去它的绝对值,这里的n位数值位的位数
补码表示的优点
- 首先,如果想给-4加个-1,只需要将这两个数的全部八个比特位相加(包括符号位),并且将计算结果中超出的部分丢弃
其次,使用二进制补码可以使负数的位左移和右移操作得到跟正数相同的效果,即每项左移一位就将自身的数值乘以2,每向右移一位就将自身的数值除以2.要达到此目的,对有符号整数的右移有一个额外的规则:当对整数进行位右移操作时,遵循与无符号整数相同的规则,但是对于移位产生的空白位使用符号位进行填充,而不是0