swift 可选值详解2

170 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情

可选链

我们都知道在OC 中我们给一个 nil 对象发送消息什么也不会发生, Swift 中我们是没有办法向一个 nil 对象直接发送消息的,但是借助可选链可以达到类似的效果。我们看下面两段代码:

let str: String? = "abc"
let upperStr = str?.uppercased() // Optional<"ABC">
var str1: String?
let upperStr1 = str1?.uppercased() // nil

我们再来看下面这段代码输出什么?

let str: String? = "zhang"
let upperStr = str?.uppercased().lowercased()

同样的可选链对于下标和函数调用也适用。

var closure: ((Int) -> ())?
/// closure 为 nil 不执行
closure?(1)

let dict = ["one": 1, "two": 2]
///Optional(1)
var one = dict["one"]
///nil
var three = dict["three"]
print(one, three)

?? 运算符 (空合并运算符)

( a ?? b ) 将对可选类型 a 进行空判断,如果 a 包含一个值就进行解包,否则就返回 一个默认值 b

  • 表达式 a 必须是 Optional 类型
  • 默认值 b 的类型必须要和 a 存储值的类型保持一致。
var q: Int? = 8
var value: Int
value = q ?? 0

print(value)

运算符重载与自定义

运算符重载

读者在认识重载运算符之前,首先应该清楚重载的概念。重载的概念最初是针对函数的,对同一个函数名设置不同的参数类型以实现不同的功能被称为函数的重载。
下面我们自定义一个圆形的类,通过重载加号运算符 + 来实现对圆形类实例的相加操作。
设计圆形类如下,其中有两个属性,分别表示圆形半径与圆心:

class Circle {
    var center: (Double, Double)
    var radius: Double
    init(center: (Double, Double), radius: Double) {
        self.center = center
        self.radius = radius
    }
}

定义两个Circle实例进行相加操作时应执行这样的运算:两个Circle实例相加返回一个新的Circle实例,并且这个新的Circle实例的圆心为两个操作数Circle实例半径的和,重载加法运算符如下:

func +(param1: Circle, param2: Circle) -> Circle {
    return Circle(center: param1.center, radius: param1.radius + param2.radius)
}

比如在开发中我们定义了一个二维向量,这个时候我们想对两个向量进行基本的操作,那么我们就可以通过重载运算符来达到我们的目的。

struct Vector {
    let x: Int
    let y: Int
}

extension Vector {
    static func + (fistVector: Vector, secondVector: Vector) -> Vector {
        return Vector(x: fistVector.x + secondVector.x, y: fistVector.y + secondVector.y)
    }
    
    static prefix func - (vector: Vector) -> Vector {
            return Vector(x: -vector.x, y: -vector.y)
    }
    
    static func - (fistVector: Vector, secondVector: Vector) -> Vector {
            return fistVector + -secondVector
    }

}

var x = Vector(x: 10, y: 20)
var y = Vector(x: 20, y: 30)
var z = x + y

print(z)
var u = -z
print(u)

输出打印

Vector(x: 30, y: 50)
Vector(x: -30, y: -50)