目录
可选项的本质
/// 一、可选项的本质
func optionalNature() -> Void {
//1、可选项的本质是enum
do{
print("-------1----------")
/**
可选项的本质是enum类型
public enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
public init(_ some: Wrapped)
}
*/
var num1:Int? = nil
num1 = 10
print("num1:",String(describing: num1))//num1: Optional(10)
var num2:Optional<Int> = Optional<Int>.none
num2 = Optional<Int>.some(10)
print("num2:",String(describing: num2))//num2: Optional(10)
var num3:Int? = Optional<Int>.none
num3 = Optional<Int>.some(10)
print("num3:",String(describing: num3))//num3: Optional(10)
}
//2、可选项的本质是enum
do{
print("------2-------")
var age: Int? = 10
age = nil
let age0: Optional<Int> = Optional<Int>.some(10)
let age1: Optional = .some(10)
let age2 = Optional.some(10)
var age3 = Optional(10)
age3 = .none
//打印时 as Any 可消除警告
print(age as Any, // nil
age0 as Any, // Optional(10)
age1 as Any, // Optional(10)
age2 as Any, // Optional(10)
age3 as Any, // nil
separator:"\n"
)
switch age {
case Optional<Int>.none:
print("none") //none
case Optional<Int>.some(let v):
print("v = ",v)
}
switch age {
case let v ://直接将age的值绑定到v 不会自动解包
print(v as Any)// nil
}
}
//3、可选项的本质是enum
do{
print("-------3---------")
let age:Int? = 10
switch age{
case let .some(v)://关联值绑定
print("some", v) //some 10
case .none:
print("none")
}
switch age {
case let v?://关联值绑定
print("some", v) //some 10
case nil:
print("none")
}
//等价于这种写法
if let v = age {
print(v) //10
}else{
print("nil")
}
}
}
多重可选项的本质
/// 二、多重可选项的本质
func mutipleOptinal() -> Void {
//1、可选项的本质就是带泛型的枚举
do{
print("-------1-------")
let age1: Int? = 10
var age2: Int?? = age1
age2 = nil
//上面写法等价于下面这种写法
age2 = Optional.some(Optional.some(10))
age2 = .none
print(String(describing: age2))//nil
}
//2、可选项的本质就是带泛型的枚举
do{
print("-------2-------")
var age1: Optional<Optional> = .some(.some(10))
age1 = .none
age1 = 10
print(age1 as Any)//Optional(Optional(10))
let age2: Int?? = 10
print(age2 as Any)//Optional(Optional(10))
let age3:Optional<Optional<Int>> = 20
print(age3 as Any)//Optional(Optional(20))
}
}
多重可选项的本质2
/// 三、多重可选项的本质2
func mutipleOptinal2() -> Void {
do{
print("--------1---------")
let num1:Int? = nil
let num2:Int?? = num1
let num3:Int?? = nil
print(num1 == num2)//true
print(num1 == num3)//false
print(num2 == num3)//false
}
do{
print("--------2---------")
let num1:Optional<Int> = Optional<Int>.none //nil
let num2:Optional<Optional<Int>> = Optional<Int>.none //相当于 num1 注意这里的类型区别
let num3:Optional<Optional<Int>> = Optional<Optional<Int>>.none//相当于 nil
print(num1 == num2)//true
print(num1 == num3)//false
print(num2 == num3)//false
}
do{
print("--------3---------")
enum Test<T>{
case none
case some(x:T)
}
// let num1:Test<Int> = Test<Int>.none //nil
// let num2:Test<Test<Int>> = Test<Int>.none //num1 注意这里的类型区别
// let num3:Test<Test<Int>> = Test<Test<Int>>.none //nil
// print(num1,num2,num3,separator:"\n")
}
do{
print("----------4---------")
var num1:Optional<Int> = 10 //.some(10)
var num2:Optional<Optional<Int>> = 10 //.some(.some(10))
var num3:Optional<Optional<Int>> = Optional<Optional<Int>>.some(10)
//比较的时候然后会自动解包??
print(num1 == num2)//true
print(num1 == num3)//true
print(num2 == num3)//true
num1 = .none//Optional<Int>.none
num2 = .none//Optional<Optional<Int>>.none
num3 = .none//Optional<Optional<Int>>.none
print(num1 == num2)//false
print(num1 == num3)//false
print(num2 == num3)//false
}
}
看下图分析:
num1 == num3; // true 非空的可选项比较会递归解包
num2 == num4; // false 空也是有类型的,它俩类型不同所以不相等。
这里重点介绍下num5,num5是非空的,所以比较时会递归解包
num2 == num5; // ture
溢出运算符
/// 四、溢出运算符
func overFlowOperator()->Void{
//Int8的取值范围是 -128 - 127
//溢出加
var num = Int8.max
//num+=1//溢出报错
num &+= 1
print(num)//-128
//溢出减
var num2 = Int8.min
//num2 -= 1//溢出报错
num2 &-= 1
print(num2)//127
//溢出乘
var num3 = Int8.max
//num3 *= 3//溢出报错
num3 &*= 2 //相当于 num3 + num3
print(num3)//-2
}
重载运算符
/// 五、重载运算符
//需要定义成全局的才可以定义重载运算符
struct Point{
var x:Int
var y:Int
init(_ x:Int,_ y:Int) {
self.x = x
self.y = y
}
//重载 + 号运算符
static func + (p1:Point,p2:Point) -> Point {
Point(p1.x + p2.x,p1.y + p2.y)
}
//重载 - 号运算符
static func - (p1:Point,p2:Point) -> Point {
Point(p1.x - p2.x,p1.y - p2.y)
}
//重载 += 号运算符
static func += (p1: inout Point,p2:Point){
// p1.x += p2.x
// p1.y += p2.y
p1 = p1 + p2
}
//实现 prefix ++
static prefix func ++ (p:inout Point)->Point{
p += Point(1,1)
return p
}
//实现 postfix ++
static postfix func ++ (p:inout Point)->Point{
let temp = p
p += Point(1,1)
return temp
}
//实现==
static func == (p1:Point,p2:Point)->Bool{
(p1.x == p2.x && p1.y == p2.y)
}
}
func overloadOperator() -> Void {
var p1 = Point(1,2)
let p2 = Point(10,20)
let p3 = p1 + p2
let p4 = p2 - p1
print(p3,p4)//Point(x: 11, y: 22) Point(x: 9, y: 18)
print("--------------")
p1 += p2
print(p1)//Point(x: 11, y: 22)
let p5 = ++p1
print(p5)//Point(x: 12, y: 23)
let p6 = p1++
print(p6)//Point(x: 12, y: 23)
print("--------------")
let p7 = Point(10,20)
print(p1 == p7)//false
print(p2 == p7)//true
}
Equatable的用法
/// 六、Equatable的用法
func equatableUse() -> Void {
struct Point2:Equatable{
var x:Int,y:Int
init(_ x:Int,_ y:Int) {
self.x = x
self.y = y
}
static func == (p1:Point2,p2:Point2)->Bool{
(p1.x == p2.x) && (p1.y == p2.y)
}
}
struct Point3:Equatable {
var x:Int,y:Int
}
//要想得知2个实例是否等价,一般做法是遵守Equatable 协议,重载== 运算符
//与此同时,等价于重载了 != 运算符
let p1 = Point2(1,10)
let p2 = Point2(2,20)
print(p1 == p2)//false
//如果不遵从Equatable协议不会自动生成 != 重载
print(p1 != p2)//true
print("-------------")
//Swift为以下类型提供默认的Equatable 实现
//没有关联类型的枚举
//只拥有遵守 Equatable 协议关联类型的枚举
//只拥有遵守 Equatable 协议存储属性的结构体
let p3 = Point3(x: 1, y: 1)
let p4 = Point3(x: 2, y: 2)
print(p3 == p4)//false
print(p3 != p4)//true
print("-------------")
//引用类型比较存储的地址值是否相等(是否引用着同一个对象),使用恒等运算符=== 、!==
class Person{
}
let per1 = Person()
var per2 = Person()
print(per1 === per2)//false
print(per1 !== per2)//true
per2 = per1
print(per1 === per2)//true
}
行者常至,为者常成!