特殊运算符以及运算符的重载

溢出运算符

目前的溢出运算符有三种&+ &- &*

var num:Int8 = 127
print(Int8.max)   //127
print(Int8.min)  //-128
num += 1
print(num) //抛出异常

正常做运算如果溢出就会报错,比如上述代码,Int8支持的最大数字是127,再加1就溢出了,系统会抛出异常,解决办法就是用溢出运算符&+

var num:Int8 = 127
print(Int8.max)   //127
print(Int8.min)  //-128
num &+= 1
print(num)    //-128

加完之后的值,对256取余数,然后再减去256,比如128%256  - 256 = -128,如果是负数则加256, &- &*也同样是这个道理,最终的结果只能是[-128,127]这个区间的值

运算符重载

func +(_ dir:Dircetion,_ dir1:Dircetion) -> Dircetion
{
    Dircetion(x: dir.x + dir1.x, y: dir.y + dir1.y)
}

struct Dircetion {
    var x:Int
    var y:Int
}

var dir = Dircetion(x: 10, y: 10) + Dircetion(x: 20, y: 20)
print(dir.x,dir.y)  //30 30

基本的运算符重载,就是上述代码,比如可以重载个加号,实现结构体之间的加法运算

struct Dircetion {
    var x:Int
    var y:Int
    static func +(_ dir:Dircetion,_ dir1:Dircetion) -> Dircetion
    {
        Dircetion(x: dir.x + dir1.x, y: dir.y + dir1.y)
    }
}

struct Person {
    var age:Int
    static func +(_ person1:Person,_ person2:Person) -> Int
    {
        person1.age + person2.age
    }
}

var dir = Dircetion(x: 10, y: 10) + Dircetion(x: 20, y: 20)
print(dir.x,dir.y)  //30 30
var totalAge = Person(age: 10) + Person(age: 30)
print(totalAge)   //40

当然这种重载最好写在各自的结构体内部,这样不管从调用还是查看代码都要清晰的多

前缀运算符和后缀运算符

struct Dircetion:CustomStringConvertible {
    var x:Double = 0.0
    var y:Double = 0.0
    var description: String
    {
        String(format: "x:\(self.x) y:\(self.y)")
    }
    static let offset_x:Double = 0.01
    static let offset_y:Double = 0.01
    static prefix func ++(_ dir:inout Dircetion) -> Dircetion
    {
        dir.x += self.offset_x
        dir.y += self.offset_y
        return dir
    }
    static postfix func ++(_ dir:inout Dircetion) -> Dircetion
    {
        let temp = dir
        dir.x += self.offset_x
        dir.y += self.offset_y
        return temp
    }
    
}
var dir:Dircetion = Dircetion(x: 10, y: 10)
let result = ++dir
let result1 = dir++
print(result)    //x:10.01 y:10.01
print(result1)   //x:10.01 y:10.01
print(dir)       //x:10.02 y:10.02

prefix就是前缀postfix就是后缀运算符,都是修饰的++,可以看到result和result1的输出结果是一样的,因为result1调用的是后缀,后缀会先赋值再计算,所以result1还是没加之前的dir

比较运算符

Equatable协议

Equatable协议的目的就是判断是否相等

struct Person :Equatable {
    var userID:String = ""
    var name:String = ""
}
var p1 = Person(userID: "12345",name: "张三")
var p2 = Person(userID: "12345",name: "张大壮")
print(p1 == p2)   //false

一般继承了Equatable系统会生成一个比较方式,类除外,类必须自己写,但这个是可以自定义的,和运算符重载一毛一样

struct Person :Equatable {
    var userID:String = ""
    var nickName:String = ""
    static func ==(_ p1:Person,_ p2:Person) -> Bool {
        p1.userID == p2.userID
    }
}
var p1 = Person(userID: "12345",nickName: "蛋蛋的哀伤")
var p2 = Person(userID: "12345",nickName: "惜雨")
print(p1 == p2)   //true

比如上述代码,重载了==,只比较userID,哪怕是两个不同的Person类,但userID是一样的,就默认是一个用户,然后可以做些摒弃之类的操作,

Equatable在枚举和结构体系统是会生成一个默认的==符号重载,但类是必须自定义的,如果没有继承Equatable协议的结构体,枚举,类

Comparable协议

比较运算符,和==类似,不过区别是> < >= <=这些,就不赘述了和==的重载方式一样,需要自定义,内容想咋写咋写,只要能编译过

自定义运算符

infix operator <<<
func <<<(_ v1:inout Int,_ v2:Int) -> Int{
    (v1 << v2) << v2
}
var v1:Int = 1
print((v1 <<< 4)) //256

基础的自定义运算符,就是这样,其中 infix 代表中缀,就是放中间的,一般中缀可以传递左右两个参数,前缀(prefix)和后缀(postfix)只能传递一个参数,还写一个运算符的定义组,后面的运算符遵守这个组,则默认设置组里面的参数,类似一种自定义运算符的配置文件,定义运算符的优先级,使用方式等等

直接截图吧,懒得一个个敲了,定义方式和前面一样,只是多了个级组来设置各种

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值