美文网首页
Swift 运算符

Swift 运算符

作者: 黎明s | 来源:发表于2018-11-28 17:44 被阅读0次

demo 地址:https://share.weiyun.com/5gIsJHA

运算符是一个符号,用于告诉编译器执行一个数学或逻辑运算。
Swift 提供了以下几种运算符:

  • 算术运算符
  • 比较运算符
  • 逻辑运算符
  • 位运算符
  • 赋值运算符
  • 区间运算符
  • 其他运算符

下面将为大家详细介绍算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符及其他运算符。

算术运算符

以下表格列出了 Swift 语言支持的算术运算符,其中变量 A 为 10,变量 B 为 20:

运算符 描述 实例
+ 加号 A + B 结果为 30
减号 A - B 结果为 -10
* 乘号 A * B 结果为 200
/ 除号 B / A 结果为 2
% 求余 B % A 结果为 0

注意:swift3 中已经取消了++--

实例

以下为算术运算的简单实例:

import Cocoa

var A = 10
var B = 20

print("A + B 结果为:\(A + B)")
print("A - B 结果为:\(A - B)")
print("A * B 结果为:\(A * B)")
print("B / A 结果为:\(B / A)")
A += 1   // 类似 A++
print("A += 1 后 A 的值为 \(A)")
B -= 1   // 类似 B--
print("B -= 1 后 B 的值为 \(B)")

以上程序执行结果为:

A + B 结果为:30
A - B 结果为:-10
A * B 结果为:200
B / A 结果为:2
A += 1 后 A 的值为 11
B -= 1 后 B 的值为 19

比较运算符

以下表格列出了 Swift 语言支持的比较运算符,其中变量 A 为 10,变量 B 为 20:

运算符 描述 实例
== 等于 (A == B) 为 false
!= 不等于 (A != B) 为 true
> 大于 (A > B) 为 false
< 小于 (A < B) 为 true
>= 大于等于 (A >= B) 为 false
<= 小于等于 (A <= B) 为 true
实例

以下为比较运算的简单实例:

import Cocoa

var A = 10
var B = 20

print("A == B 结果为:\(A == B)")
print("A != B 结果为:\(A != B)")
print("A > B 结果为:\(A > B)")
print("A < B 结果为:\(A < B)")
print("A >= B 结果为:\(A >= B)")
print("A <= B 结果为:\(A <= B)")

以上程序执行结果为:

A == B 结果为:false
A != B 结果为:true
A > B 结果为:false
A < B 结果为:true
A >= B 结果为:false
A <= B 结果为:true

逻辑运算符

以下表格列出了 Swift 语言支持的逻辑运算符,其中变量 A 为 true,变量 B 为 false

运算符 描述 实例
&& 逻辑与;如果运算符两侧都为 true 则为 true (A && B) 为 false
|| 逻辑或;如果运算符两侧至少有一个为 true 则为 true (A || B) 为 true
! 逻辑非;布尔值取反,使得truefalsefalsetrue !(A && B) 为 true

以下为逻辑运算的简单实例:

import Cocoa

var A = true
var B = false

print("A && B 结果为:\(A && B)")
print("A || B 结果为:\(A || B)")
print("!A 结果为:\(!A)")
print("!B 结果为:\(!B)")

以上程序执行结果为:

A && B 结果为:false
A || B 结果为:true
!A 结果为:false
!B 结果为:true

位运算符

位运算符用来对二进制位进行操作:

  • ~:取反:单目运算符
    具有右结合性;其功能是对参与运算的数的各二进位按位求反。
    例如:
~(1001)
结果为:0110
  • &:按位与
    是双目运算符;其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。
  • |:按位或
    是双目运算符,其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。
  • ^:按位异或
    是双目运算符,其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1;反之为0。参与运算数仍以补码出现。
  • <<:左移运算符:
    是双目运算符。左移n位就是乘以2的n次方。 其功能把<<左边的运算数的各二进位全部左移若干位,由<<右边的数指定移动的位数,高位丢弃,低位补0。
    1. 运算规则:
      按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
    2. 语法格式:
      需要移位的数字 << 移位的次数

注意:当最高位溢出包括1时,则不适用规则左移n位就是乘以2的n次方。

  • >>:无符号右移运算符

    1. 运算规则:
      按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1。
    2. 语法格式:
      需要移位的数字 >> 移位的次数
    3. 示例: 11 >> 2,则是将数字11右移2位
      计算过程:
      11的二进制形式为:0000 1011,然后把低位的最后两个数字移出,因为该数字是正数,所以在高位补零。则得到的最终结果是0000 0010。转换为十进制是2。
    4. 数学意义:
      右移一位相当于除2,右移n位相当于除以2的n次方。这里是取商,不包括余数。
  • >>>:有符号右移运算符

    1. 运算规则:
      二进制形式把所有的数字向右移动对应位数,低位移出(舍弃),高位的空位补零。对于正数来说和带符号右移相同,对于负数来说不同。 其他结构和>>相似。
p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

如果指定 A = 156; 及 B = 63; 两个变量对应的二进制为:
A = 1001 1100
B = 0011 1111

运算符 图解 实例
& https://share.weiyun.com/52ERV3D (A & B) 结果为 28,二进制为 0001 1100
| https://share.weiyun.com/5tKae28 (A | B) 结果为 191,二进制为 1011 1111
^ https://share.weiyun.com/5kp5F0h (A ^ B) 结果为 163,二进制为 1010 0011
~ https://share.weiyun.com/53vcuaN (~A) 结果为 99,二进制为 0110 0011
<< https://share.weiyun.com/5L085l0 (A << 1) 结果为 312,二进制为 0001 0011 1000
>> https://share.weiyun.com/5j3GIeV (A >> 1) 结果为 78,二进制为 0100 1110

以下为位运算的简单实例:

import Cocoa

var A = 60  // 二进制为 0011 1100
var B = 13 // 二进制为 0000 1101

print("A&B 结果为:\(A&B)")
print("A|B 结果为:\(A|B)")
print("A^B 结果为:\(A^B)")
print("~A 结果为:\(~A)")

以上程序执行结果为:

A&B 结果为:12
A|B 结果为:61
A^B 结果为:49
~A 结果为:-61

赋值运算

  • =
    简单的赋值运算,指定右边操作数赋值给左边的操作数
  • +=
    相加后再赋值,将左右两边的操作数相加后再赋值给左边的操作数
  • -=
    相减后再赋值,将左右两边的操作数相减后再赋值给左边的操作数
  • *=
    相乘后再赋值,将左右两边的操作数相乘后再赋值给左边的操作数
  • /=
    相除后再赋值,将左右两边的操作数相除后再赋值给左边的操作数
  • %=
    求余后再赋值,将左右两边的操作数求余后再赋值给左边的操作数
  • <<=
    按位左移后再赋值
  • >>=
    按位右移后再赋值
  • &=
    按位与运算后赋值
  • ^=
    按位异或运算符后再赋值
  • |=
    按位或运算后再赋值
运算符 示例
= C = A + BA + B 的运算结果赋值给 C
+= C += A 相当于 C = C + A
-= C -= A 相当于 C = C - A
*= C *= A 相当于 C = C * A
/= C /= A 相当于 C = C / A
%= C %= A 相当于 C = C % A
<<= C <<= 2 相当于 C = C << 2
>>= C >>= 2 相当于 C = C >> 2
&= C &= 2 相当于 C = C & 2
^= C ^= 2 相当于 C = C ^ 2
|= C |= 2 相当于 C = C | 2

以下为赋值运算的简单实例:

var A = 5; var B = 6; var C = 0
        
printConditionD3(A: A, B: B, C: C)
C = A + B; print("A + B 结果为 \(C)")
        
A = 3; C = 5; printConditionD2(A: A, C: C)
C += A; print("C += A 结果为 \(C)")
        
A = 10; C = 15; printConditionD2(A: A, C: C)
C -= A; print("C -= A 结果为 \(C)")
        
A = 6; C = 7; printConditionD2(A: A, C: C)
C *= A; print("C *= A 结果为 \(C)")
        
A = 4; C = 36; printConditionD2(A: A, C: C)
C /= A; print("C /= A 结果为 \(C)")
        
A = 3; C = 8; printConditionD2(A: A, C: C)
C %= A; print("C %= A 结果为 \(C)")
        
C = 0b0100; A = 0b0001; printConditionB(A: A, C: C)
C <<= A; print("C <<= A 结果为 \(numToStr(num: C))")
        
C = 0b100; A = 1; printConditionB(A: A, C: C)
C >>= A; print("C >>= A 结果为 \(numToStr(num: C))")
        
C = 0b1001; A = 0b1010; printConditionB(A: A, C: C)
C &= A; print("C &= A 结果为 \(numToStr(num: C))")
        
C = 0b1001; A = 0b1010; printConditionB(A: A, C: C)
C ^= A; print("C ^= A 结果为 \(numToStr(num: C))")
        
C = 0b1001; A = 0b1010; printConditionB(A: A, C: C)
C |= A; print("C |= A 结果为 \(numToStr(num: C))")
func numToStr(num: Int) -> String
{
    return "0b\(String(format: "%04d", Int(String(num, radix: 2, uppercase: false))!))"
}
    
func printConditionD3(A: Int, B: Int, C: Int)
{
    print("当 A = \(A)、B = \(B)、C = \(C) 时,", separator: ",", terminator: " ")
}
    
func printConditionD2(A: Int, C: Int)
{
    print("当 A = \(A)、C = \(C) 时,", separator: ",", terminator: " ")
}
    
func printConditionB(A: Int, C: Int)
{
    print("当 A = \(numToStr(num: A))、C = \(numToStr(num: C)) 时,", separator: ",", terminator: " ")
}

执行结果为:

当 A = 5、B = 6、C = 0 时, A + B 结果为 11
当 A = 3、C = 5 时, C += A 结果为 8
当 A = 10、C = 15 时, C -= A 结果为 5
当 A = 6、C = 7 时, C *= A 结果为 42
当 A = 4、C = 36 时, C /= A 结果为 9
当 A = 3、C = 8 时, C %= A 结果为 2
当 A = 0b0001、C = 0b0100 时, C <<= A 结果为 0b1000
当 A = 0b0001、C = 0b0100 时, C >>= A 结果为 0b0010
当 A = 0b1010、C = 0b1001 时, C &= A 结果为 0b1000
当 A = 0b1010、C = 0b1001 时, C ^= A 结果为 0b0011
当 A = 0b1010、C = 0b1001 时, C |= A 结果为 0b1011

区间运算符

Swift 提供了两个区间的运算符:闭区间运算符(...)和半开区间运算符(..<

  • 闭区间运算符(...
    闭区间运算符(a...b)定义一个包含从a到b(包括a和b)的所有值的区间,b必须大于等于a。 ‌ 闭区间运算符在迭代一个区间的所有值时是非常有用的,如在for-in循环中。
  • 半开区间运算符(..<
    半开区间(a..<b)定义一个包含从 a 到 b(包括a,不包括 b)的所有值的区间,b 必须大于a。
运算符 实例
闭区间运算符(... 1...5 区间值为 1, 2, 3, 4 和 5
半开区间运算符(..< 1..<5 区间值为 1, 2, 3, 和 4

以下为区间运算的简单实例:

import Cocoa

print("闭区间运算符:")
for index in 1...5 {
    print("\(index) * 5 = \(index * 5)")
}

print("半开区间运算符:")
for index in 1..<5 {
    print("\(index) * 5 = \(index * 5)")
}

以上程序执行结果为:

1 * 5 = 5
2 * 5 = 10
3 * 5 = 15
4 * 5 = 20
5 * 5 = 25
半开区间运算符:
1 * 5 = 5
2 * 5 = 10
3 * 5 = 15
4 * 5 = 20

空合运算符

这个操作符可以用来快速的对 nil 进行判断,当左侧的值是 非 nil时返回其value左侧的值,为nil时返回其右侧的值。
两个条件:表达式a必须是可选类型,默认值b的类型必须要和a存储值的类型一致。空合并运算符 (a ?? b) 将对可选类型a进行空判断,如果a包含一个值就进行解封,否则就返回一个默认值b。

//空合运算符
var strResult : String?
let strDefault = "default string"
var strNew = strResult ?? strDefault
print("strNew:\(strNew)")
        
strResult = "result string"
strNew = strResult ?? strDefault
print("strNew:\(strNew)")

以上程序的执行结果为:

strNew:default string
strNew:result string

其他运算符

Swift 提供了其他类型的的运算符,如一元、二元和三元运算符。

  • 一元运算符对单一操作对象操作(如-a)。一元运算符分前置运算符和后置运算符,前置运算符需紧跟在操作对象之前(如!b),后置运算符需紧跟在操作对象之后(例如c!)。

备注:在Java/C没有类似c!的语法, 在Swift中用在Optional类型取值。

  • 二元运算符操作两个操作对象(如2 + 3),是中置的,因为它们出现在两个操作对象之间。
  • 三元运算符操作三个操作对象,和 C 语言一样,Swift 只有一个三元运算符,就是三目运算符(a ? b : c)。

运算符重载

现有一个向量,我们重载它的+-*+=运算符。

注意: =是不可以进行重载的。

struct Vector3
{
    var x: Double = 0.0
    var y: Double = 0.0
    var z: Double = 0.0
}

注意:以下重载函数要写在class外部,且只能是1个或2个参数

  • 重载 +
// 重载加号(+)
func + (left: Vector3, right: Vector3) -> Vector3 {
    return Vector3(x: left.x + right.x, y: left.y + right.y, z: left.z + right.z)
}
  • 重载减号-
func - (left: Vector3, right: Vector3) -> Vector3 {
    return Vector3(x: left.x - right.x, y: left.y - right.y, z: left.z - right.z)
}
  • 重载乘号*
func * (left: Vector3, right: Vector3) -> Double {
    return left.x * right.x + left.y * right.y + left.z * right.z
}
  • 重载负号-
/*
 重载负号(-),只有一个参数
 由于不知道“-”是放在参数的左侧还是右侧,
 故需要添加关键字prefix,代表“-”是在参数的左侧
 */
prefix func - (value: Vector3) -> Vector3 {
    return Vector3(x: -value.x, y: -value.y, z: -value.z)
}
  • 重载+=
/*
 重载 +=  ,
 由于是把该操作会使left值发生改变,故left需要用到关键字 inout;
 由于“+”方法在之前定义过,故在这个方法中可以直接使用“+”方法
 */
func += (left: inout Vector3, right: Vector3) -> Vector3 {
    left = left + right
    return left
}

实例

var v1 = Vector3(x: 3.0, y: 4.0, z: 5.0)
var v2 = Vector3(x: 7.0, y: 9.0, z: 6.0)
        
print("v1 + v2 结果为:\(v1 + v2)")
print("v1 - v2 结果为:\(v1 - v2)")
print("v1 * v2 结果为:\(v1 * v2)")
print("-v1 结果为:\(-v1)")
print("v1 += v2 结果为:\(v1 += v2)")

以上程序的执行结果为:

v1 + v2 结果为:Vector3(x: 10.0, y: 13.0, z: 11.0)
v1 - v2 结果为:Vector3(x: -4.0, y: -5.0, z: -1.0)
v1 * v2 结果为:87.0
-v1 结果为:Vector3(x: -3.0, y: -4.0, z: -5.0)
v1 += v2 结果为:Vector3(x: 10.0, y: 13.0, z: 11.0)

自定义运算符

对于系统中没有的运算符,需要通过 operator 关键字来定义操作符。

注意:这些函数仍要写在 class 外面。

  • 操作符在参数后面,使用关键字 postfix
// 对于系统中没有的运算符,需要通过 operator 来定义操作符
// postfix 表示操作符应在参数的后面
postfix operator +++
postfix func +++ (vector: inout Vector3) -> Vector3 {
    vector = vector + Vector3(x: 1.0, y: 1.0, z: 1.0)
    return vector
}
  • 操作符应在参数的前面,使用关键字 prefix
// prefix 表示操作符应在参数的前面
prefix operator ---
prefix func --- (vector: inout Vector3) -> Vector3
{
    vector = vector - Vector3(x: 1.0, y: 1.0, z: 1.0)
    return vector
}
  • 中间运算符 infix
infix operator **<: BTPrecedenceL
precedencegroup BTPrecedenceL {
    associativity: left             // 左结合
    higherThan: AdditionPrecedence  // 优先级高于加法运算符
}

func **< (x: Double, y: Double) -> Double {
    return x * y
}
infix operator **>: BTPrecedenceR
precedencegroup BTPrecedenceR {
    associativity: right            //右结合
    lowerThan: AdditionPrecedence   // 优先级低于加法运算符
}

func **> (x: Double, y: Double) -> Double {
    return x * y
}

实例

var v2 = Vector3(x: 7.0, y: 9.0, z: 6.0)

print("v2+++ 结果为:\(v2+++)")
print("---v2 结果为:\(---v2)")

let a = 3.0
let b = 2.0
let c = 4.0
        
print("a **< b **< c = \(a **< b **< c)")
print("1.0 + a **< b **< c = \(1.0 + a **< b **< c)")
print("a **> b **> c = \(a **> b **> c)")
print("1.0 + a **> b **> c = \(1.0 + a **> b **> c)")

以上程序的执行结果为:

v2+++ 结果为:Vector3(x: 8.0, y: 10.0, z: 7.0)
---v2 结果为:Vector3(x: 7.0, y: 9.0, z: 6.0)

a **< b **< c = 24.0
// 此处先计算  a **< b **< c,再加1.0 
1.0 + a **< b **< c = 25.0
a **> b **> c = 24.0
// 此处先计算 1.0 + a
1.0 + a **> b **> c = 32.0

运算符优先级

在一个表达式中可能包含多个有不同运算符连接起来的、具有不同数据类型的数据对象;由于表达式有多种运算,不同的运算顺序可能得出不同结果甚至出现错误运算错误,因为当表达式中含多种运算时,必须按一定顺序进行结合,才能保证运算的合理性和结果的正确性、唯一性。

优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最低的优先级。

相同优先级中,按结合顺序计算。大多数运算是从左至右计算,只有三个优先级是从右至左结合的,它们是单目运算符、条件运算符、赋值运算符。

基本的优先级需要记住:

  • 指针最优,单目运算优于双目运算,如正负号
  • 先乘除(模),后加减
  • 先算术运算,后移位运算,最后位运算。请特别注意:1 << 3 + 2 & 7 等价于 (1 << (3 + 2))&7
  • 逻辑运算最后计算

详细的优先级参见下表:https://share.weiyun.com/5AuIR4J

相关文章

  • swift 运算符

    Swift 基本运算符 标签(空格分隔): swift 运算符 zybuluo swift 运算符 特性 赋值运算...

  • Swift 基本语法(二)— 运算符

    swift 运算符1.赋值运算符“=” 没有返回值, 比较运算符“==” 返回bool值。 这是swift比OC...

  • Swift002-运算符和流程控制语句

    Swift002-运算符和流程控制语句 运算符 Swift支持大多数标准C运算符,并有所改进。 赋值运算符(=)不...

  • 赋值和算数运算符

    基本概念 一元运算符、二元运算符、三元运算符Swift 只有一个三元运算符 a ? b : c Swift 运算符...

  • iOS开发 - 「Swift 学习」Swift 区间运算

    Swift 区间运算符 Swift提供了两个区间运算符 运算符描述实例闭区间运算符闭区间运算符(a...b)定义一...

  • swift运算符

    溢出运算符 Swift的算数运算符出现溢出时会抛出运行时错误 Swift有溢出运算符(&+、&-、&*),用来支持...

  • Swift 高级运算符 ⑬

    1. 溢出运算符 Swift 的算数运算符出现溢出时,会抛出运行时错误 Swift 有溢出运算符(&+、&-、&*...

  • 17-Swift高级运算符

    1.溢出运算符 Swift的算数运算符出现溢出时会抛出运行时错误 Swift有溢出运算符(&+、&-、&*),用来...

  • 高级运算符

    溢出运算符 Swift的算数运算符出现溢出时会抛出运行时错误Swift有溢出运算符(&+、&-、&*),用来支持溢...

  • 每天学一点Swift---- 运算符函数

    一.运算符重载 1. Swift的运算符提供了良好的可扩展性,Swift不仅允许开发者重新定义已有的运算符(运算符...

网友评论

      本文标题:Swift 运算符

      本文链接:https://www.haomeiwen.com/subject/bajjqqtx.html