Swift 运算符

2018-11-28  本文已影响0人  黎明s

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时,则不适用规则左移n位就是乘以2的n次方。

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 提供了两个区间的运算符:闭区间运算符(...)和半开区间运算符(..<

运算符 实例
闭区间运算符(... 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 提供了其他类型的的运算符,如一元、二元和三元运算符。

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

运算符重载

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

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

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 外面。

// 对于系统中没有的运算符,需要通过 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 operator ---
prefix func --- (vector: inout Vector3) -> Vector3
{
    vector = vector - Vector3(x: 1.0, y: 1.0, z: 1.0)
    return vector
}
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

运算符优先级

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

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

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

基本的优先级需要记住:

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

上一篇 下一篇

猜你喜欢

热点阅读