25.1 位运算符
说明:
Swift
支持C
语言中的全部位运算符
符号 | 名称 | 返回值 | 复合运算符 |
---|---|---|---|
~ |
按位取反 | 将每一个0替换成1,每一个1替换成0 | ~= |
& |
按位与 | 对两个操作数相应的位执行逻辑与运算 | &= |
^ |
按位亦或 | 对两个操作数相应的位执行逻辑或操作,都是1时产生0 | ^= |
\ |
按位或 | 对两个操作数相应的位执行逻辑或操作,都是1时产生1 | \= |
<< |
按位左移 | 左移n位的结果(左端溢出,右端补0) | <<= |
>> |
按位右移 | 右移n位的结果(右端溢出,左端补0或保存符号位而补1 | >>= |
用途:通常被用在底层开发中
- 图形编程
- 设备驱动
- 处理外部资源的原始数据(比如对自定义通信协议传输的数据进行编码和解码)
25.1.1 按位取反运算符
按位取反操作符:
~
说明:按位取反运算符
可以对一个数值的全部比特位进行取反
语法:按位取反运算符是一个前缀运算符
,需要直接放在运算的数
之前,并且它们之间不能添加任何空格
1 | // 00001111 |
25.2.2 按位与运算符
按位与操作符:
&
说明:按位与运算符
可以对两个数的比特位进行合并。它返回一个新的数,只有当两个数的对应位都为1
的时候,新数的对应位才为1
1 | // 11111100 |
25.2.3 按位或运算符
按位或运算符:
|
说明:按位或运算符
可以对两个数的比特位进行比较。它返回一个新的数,只要两个数的对应位中有任意一个为1
时,新数的对应位就为1
1 | // 10110010 |
25.2.4 按位亦或运算符
按位亦或运算符:
^
说明:按位异或运算符
可以对两个数的比特位进行比较。它返回一个新的数,当两个数的对应位不相同
时,新数的对应位就为1
1 | // 00010100 |
25.2.5 按位左移、右移运算符
说明:
有符号整数
和无符号整数
的情况有所不同。值得注意的是
位移操作 | 无符号整数 | 有符号整数 |
---|---|---|
左移<< |
丢弃溢出,低位用0 填充 |
丢弃溢出,低位用0 填充 |
右移>> |
丢弃溢出,高位用0 填充 |
丢弃溢出,高位用符号位 填充 |
注意:
有符号整数
中的负数
和其它整数不同,使用的是二进制补码
的表示形式。
减法
在底层可以用加法
实现- 可以使负数的按位左移和右移运算得到跟正数同样的
效果
技巧:移位运算(无论
有符号整数
还是无符号整数
)遵守下面定义的规则
- 将一个整数
左移
一位,等价于将这个数乘以 2
- 将一个整数
右移
一位,等价于将这个数除以 2
25.2 溢出运算符
溢出:默认情况下,当向一个整数赋超过它容量的值时,
Swift
默认会报错。这一意味着,不会真的发生溢出-除非使用溢出运算符
。
说明:Swift
提供了3
个溢出操作符,会让系统在数值溢出的时候采取阶段操作
。
溢出运算符 | 功能 |
---|---|
&+ |
溢出加法 |
&- |
溢出减法 |
&* |
溢出乘法 |
1 | /***** &+ ****/ |
数值溢出
说明:数值溢出分为
上溢
和下溢
技巧:对于整数型数值(无论是有符号
还是无符号
)
- 最大数:上溢1变成最小的数
- 最小数:下溢1变成最大的数
25.3 优先级和结合性
说明:相比
C语言
和Object-C
,Swift
的运算符优先级和结合型规则更加简洁和可预测。
25.4 运算符函数
运算符重载:
类
或结构
可以为现有的操作符提供自定义的实现。
25.4.1 中缀运算符
说明:也叫做
双目运算符
出现在两个目标
之间,比如+
1 | // 结构体(平面向量) |
25.4.2 前缀和后缀运算符
说明:
单目运算符
有前缀
和后缀
之分。
单目运算符 | 说明 | 重载使用的关键字 |
---|---|---|
前缀 |
运算符出现在值之前 | prefix |
后缀 |
运算符出现在值之后 | postfix |
1 | // 结构体(平面向量) |
25.4.3 复合赋值运算符
说明:重载
复合赋值运算符
(比如+=
、++
、--
)
- 第一个参数必需声明为
inout
类型,因为这个参数的值会在运算符函数内直接被修改注意:不能对默认的
赋值运算符
和三目条件运算符
进行重载。只有组合赋值运算符可以被重载。
1 | // 结构体(平面向量) |
25.4.4 等价操作符
说明:属于
中缀运算符
(或双目运算符
),包括==
和!=
扩展:自定义的类
和结构体
没有对等价运算符
进行默认实现,为了使用等价运算符
能对自定义的类型进行判等运算
,需要为其提供自定义实现
1 | // 结构体(平面向量) |
25.5 自定义运算符
说明:除了实现标准运算符,在
Swift
中还可以声明和实现自定义运算符。
参考:可以用来自定义运算符的字符列表请参考运算符。
语法:新的运算符要使用operator
关键字在全局作用域内进行定义,同时还要指定prefix
、infix
或者postfix
修饰符。
1 | // 结构体(平面向量) |
自定义中缀运算符的优先级和结合性
说明:自定义的
中缀运算符
也可以指定优先级
(默认为100
)和结合性
(默认为none
)
优先级 | 名称 | 说明 |
---|---|---|
left |
左结合 | 跟左边的值进行结合 |
right |
右结合 | 会跟右边的值进行结合 |
none |
非结合 | 不能跟其他相同优先级的运算符写在一起 |
注意:在定义前缀与后缀运算符的时候,如果没有指定优先级,则对同一个值同时使用前缀与后缀运算符,后缀运算符会先参与运算。
参考: Swift 标准库提供的运算符的结合性与优先级
1 | // 结构体(平面向量) |