您的位置:时时app平台注册网站 > 编程知识 > 重读 Swift 之二:Operator Declaration(运算符重载)

重读 Swift 之二:Operator Declaration(运算符重载)

2019-09-14 00:42

  对贰个数举办按位左移或按位右移,约等于对那么些数进行乘以 2 或 除以 2 的运算。将贰个整数左移一个人,等价于将以此数乘以 2,一样地,将四个整数右移一人,等价于将以此数除以 2。

let invertedBits = ~initialBits // 等于 0b11110000

如上输出结果便是 Vector(x: 2, y: 2, z: 2),到此,单目运算符的自定义就到位了。

  上个例子演示了三个肉眼中缀运算符的自定义实现。类与结构体也能提供正规单目运算符的达成。单目运算符只运算三个值。当运算符出现在值之前时,它正是前缀(比如-a),而当它出现在值之后时,它正是后缀的(举个例子 b!)。

    1.单目运算符只运算一个值,当运算符出现在值以前时,它就是前缀的(举个例子-a),而当它出现在值之后时,它正是后缀的(举个例子 i )。

}

  按位取反运算符(~)可以对一个数值的整个比特位进行取反:

import UIKit

但是编译我们会发现报错,如下![error](http://upload-images.jianshu.io/upload_images/571495-b2e1e315590d0634.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)错误是说我们上面的运算是个非结合性的运算,所谓的结合性(associativity)就是运算的先后顺序,在 Swift 2 中我们都知道还有个优先级(precedence),默认的是 100 ,它的范围是 0~200 ,这个是用来设置运算符优先级的,比如在swift 2.2 中我们完全定义一个求平方运算符就是

  按位与运算符(&)能够对五个数的比特位举办联合。它回到三个新的数,唯有当四个数的呼应位数都为 1 的时候,新数的相应位才为 1:

        2.有标识整数的移动运算相对复杂得多,这种复杂源于有号子整数的二进制表现格局:

依照大家的逻辑这里取反逻辑上应当是不利的,不过编写翻译会发掘报错

  其他比特位(平常称为数值位)存款和储蓄实际的值。有标记正整数和无符号数的囤积格局是均等的,都以从 0 早先算起。

let anotherTwoThree = Vector2D(x: 2.0, y: 3.0)

  • 3 、相比较运算符的重载关于相比运算符的重载,看名就能够猜到其意义也有五个参数的,再次来到值明确是个 Bool 类型的,如下重载 == 运算符

  等价运算符

            2.负数的存款和储蓄方式略有分化。它存款和储蓄的值的相对值等于 2 的 n 次方减去它的实际值(也正是数值位代表的值),这里的 n 为数值位的比特位数。叁个 8 比特位的数有 7 个比特位是数值位,所以是 2 的 7 次方,即 128

struct Vector { var x: Int = 0 var y: Int = 0 var z: Int = 0}

  按位或运算符(|)能够对五个数的比特位实行比较。它回到三个新的数,只要六个数的照顾位中有自由贰个为 1 时,新数的应和位就为 1:

let otherBits: UInt8 = 0b00000101

那时候再去相比较 V1 和 V2 就能现出你逻辑中的效果。常规的运算符就说起那边,下边我们来看一下自定义运算符的重载。

  与 C 语言中的算术运算符不一致,swift 中的算术运算符暗中认可是不会溢出的。全体溢出的一颦一笑都会被擒获并告诉为错误。假如想让系统允许溢出作为,能够选取选择斯威夫特中另一套默许补助溢出的运算符,举例溢出加法运算符(& )。全体这个溢出运算符都以以 & 初始的。

shiftBits << 1           // 00001000

接下来大家来写V1 V2,报错

  var unsignedOverflow = UInt8.min

let anotherVector = Vector2D(x: 2.0, y: 4.0)

  • 1、含有三个参数的运算符的重载因为运算符是一个函数,举个例子对于数组的 reduce办法我们就足以如下

    溢出乘法 &*

let secondVector = Vector2D(x: 3.0, y: 4.0)

在前边大家用 prefix operator 阐明前置运算符 ,那样前面就可以用了

  新的演算符要使用 operator 关键字在大局功效域内实行定义,同时还要指定prefix、infix 也许 postfix 修饰符:

            1.早已存在的位按钦命的位数进行左移和右移。

时时app平台注册网站 1error那是因为我们未有分明的定义那么些 ,所以编译器不识别。所以大家应该表雅培下以此运算符,准确的代码如下

  按位取反运算符是一个前缀运算符,需求一向放在运算的数以前,况兼它们中间不能增加任何空格:

}

 如上我们输入 `2 ** 2 ** 3`,就会发现结果是 256.0,这是因为我们把 associativity 设置成为了 right,所以运算从右边开始,先算 ` 2 ** 3 = 8.0`,然后再是 `2 ** 8.0 = 256.0`,如果我们把 associativity 设置成为了 left,就会发现结果是 64.0。关于更多的 associativity 和 higherThan 或者 lowerThan 之类的可以在下方参考连接中参考,这里就不一一说明了。差不多运算符重载就到这里了,如果还有什么遗漏,欢迎大家指正!> 参考:1、[swift-evolution](https://github.com/apple/swift-evolution/blob/master/proposals/0077-operator-precedence.md)2、[Operator Declaration](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/operator-declaration)

  按位左移运算符(<<)和按位右移运算符(>>)能够对三个数的富有位打开点名位数的左移和右移,可是须求服从上面定义的准绳。

}

infix operator ** func ** (x: Double, y: Double) -> Double { return pow}```上面我们就自定义了一个求平方的双目运算符 `**`,然后我们试试 `2 ** 2`就可以看到结果是 `4.0`。上面好像没有什么问题了,下面我想算一个平方的平方,拨入 2 的 2次方的 3 次方,照着逻辑应该这样写

  extension Vector2D {

 

情趣正是

  let initialBits: UInt8 = 0b00001111

优先级和结合性:运算符的优先级使得有个别运算符优先于别的运算符,高优先级的运算符会先被总括,结合性定义了长期以来优先级的运算符是怎么样结合的(左结合、右结合)

上面我们所说的都以 斯威夫特中早就存在了的运算符,那么大家能或不可能自个儿定义运算符呢?答案是无庸置疑的,在文书档案中大家得以见见那般一句话

  struct Vector2D {

let combinedVector = vector anotherVector     // combinedVector 是多个新的 Vector2D 实例,值为 (5.0, 5.0)

结果是 10 ,这里的 就意味着了一个函数,所以大家再一次写的时候能够如下

  在那几个完成中,输入参数分别被取名字为 left 和 right,代表在 运算符左边和左侧的三个 Vector2D 实例。函数再次来到了一个新的 Vector2D 实例,那一个实例的 x 和 y 分别也正是作为参数的七个实例的 x 和 y 的值之和。

*/

时时app平台注册网站 2error这里大家将要小心了,和有七个参数的运算符差异的是,独有一个参数的运算符地方是不定点的,这里的 - 能够在前能够在后,所以大家在此间还须要专心运算符的职位

  上述代码达成了 “相等” 运算符(==)来剖断五个 Vector2D 实例是或不是等于。对于 Vector2D 类型来讲,“相等” 意味着“两个实例的 x 属性和 y 属性都等于”, 那也是代码中用来开展剖断的逻辑。示例里还要也兑现了 “不等” 运算符(!=),它大约地将 “相等” 运算符的结果举办取反后再次回到。

let someBits: UInt8 = 0b10110010

}2 ** 2 ** 3 //结果是64.0

    }

}

prefix operator    prefix func     (vector: Vector) -> Vector { return Vector(x: vector.x   1, y: vector.y   1, z: vector.z   1)}

    溢出减法 &-

let greenComponent = (pink & 0x00FF00) >> 8 // greenComponent 是 0x66, 即 102

var V1 = Vector(x: 1, y: 2, z: 3)var V2 = Vector(x: 4, y: 5, z: 6)

  溢出运算符

let firstVector = Vector2D(x: 1.0, y: 2.0)

return pow

  对于简易数值,单目负号运算符能够对它们的正负性进行转移。对于 Vector2D 来讲,该运算符将其 x 和 y 属性的正负性都实行了转移。

 

自定义运算符可以由以下其中之一的 ASCII 字符 /、=、 -、 、!、*、%、<、>、&、|、^、? 以及~,或者后面语法中规定的任一个 Unicode 字符(其中包含了*数学运算符*、*零散符号(Miscellaneous Symbols)* 以及印刷符号  之类的 Unicode 块)开始。在第一个字符之后,允许使用组合型 Unicode 字符。

  // 此时 unsignOverflow 等于 0 

    2.数值溢出:数值有非常大概率现身上溢或然下溢,在对有暗号整型数值实行溢出加法或溢出减法运算时,符号位也亟需加入计算

在 Swift 3 中有些变化,如下

  要落到实处前缀也许后缀运算符,必要在宣称运算符函数的时候在 func 关键字从前线指挥部定 prefix 只怕 postfix 修饰符:

let lastSixBits: UInt8  = 0b00111111

  }

按位取反运算符(~)能够对一个数值的整个比特位进行取反:

时时app平台注册网站 3 error 报错 无法用于 Vector,那是因为 Vector 是我们自定义的二个结构体,所以编写翻译器不晓得我们要用 对那一个结构体做什么样操作。因而,在这里大家就要求用到运算符的重载。

  位运算符能够操作数据结构中每一种独立的比特位。它们经常被用在底部开采中,举例图片编程和创制设备驱动。位运算符在管理外界能源的固有数据时也特别有用,例如对自定义通讯公约传输的多寡开展编码和平化解码。

let pink: UInt32 = 0xCC6699     //能够动用移动运算对其余的数据类型实行编码和平消除码

这么我们就贯彻了 的重载,上边函数中 left 和 right 多个参数都以Vector 类型的,二个意味着运算符左边的参数贰个意味着运算符右侧的参数(那五个参数是有先后顺序的,由于加法满足加法交流律所以那边反映不出来,风乐趣的能够试一下 - 的重载,那时候就要注意顺序了),然后重返值得类型也是 Vector 类型,再来达成V1 V2的时候,就发掘赢得了一个新的 Vector 类型的值

  var unsignedOverflow = UInt8.max

let redComponent = (pink & 0xFF0000) >> 16  // redComponent 是 0xCC,即 204

唯独编写翻译的时候会报错,如下

  位运算符

    return !(left == right)

  同样的,当大家对贰个无符号整数使用溢出减法(&-)进行下溢运算也会时有产生看似的风貌:

}

Custom operators can begin with one of the ASCII characters /, =, -,  , !, *, %, <, >, &, |, ^, ?, or ~, or one of the Unicode characters defined in the grammar below (which include characters from the *Mathematical Operators*, *Miscellaneous Symbols*, and *Dingbats* Unicode blocks, among others). After the first character, combining Unicode characters are also allowed.

    static func != (left: Vector2D, right: Vector2D) -> Bool {

按位左移、右移运算符:按位左移运算符(<<)和按位右移运算符(>>)能够对贰个数的装有位进行点名位数的左移和右移,但是急需遵循上边定义的条条框框。

时时app平台注册网站 4-V1

  注意

        溢出乘法 &*

  • 1、自定义单目运算符所以大家在自定义运算符的时候要专一一下。上边大家就来回顾的自定义七个单目运算符 ,那么些运算符的法力呢便是让 Vector 中的每一个变量都加 1 ,如下

  // 此时 unsignedOverflow 等于 255

自定义中缀运算符的优先级和结合性:自定义的中缀运算符也能够钦赐优先级和结合性

那边充足一个 prefix 表示前置(前置是 postfix)。那样就足以显明运算符的职位

  有标记整数使用第 1 个比特位(通常称为符号位)来表示那些数的正负。符号位为 0 代表正数,为 1 代表负数。

 

时时app平台注册网站 5V1

  unsignedOverflow = unsignedOverflow & 1

等价运算符:自定义的类和结构体没有对等价运算符实行暗中同意达成,等价运算符经常被叫作“相等”运算符(==)与“不等”运算符(!=),自定义完成的诀窍与别的中缀运算符同样

precedencegroup ComparativePrecedence {associativity: righthigherThan: LogicalConjunctionPrecedence}infix operator ** : ComparativePrecedencefunc ** (x: Double, y: Double) -> Double {

    已经存在的位按钦命的位数举行左移和右移

let plusMinusVector = firstVector - secondVector// plusMinusVector 是多个 Vector2D 实例,并且它的值为 (4.0, -2.0)

然后大家定义三个变量 V1,V2

  无法对私下认可的赋值运算符(=)举办重载。一样地,也力无法及对三目条件运算符(a?b:c)进行重载。

    2.结合性的暗许值是 none,优先级的暗许值 100

let arr = [1, 2, 3, 4]arr.reduce

  自定义中缀运算符的优先级

    vector = vector

infix operator ** { associativity left precedence 120 }func ** (x: Double, y: Double) -> Double {

  这一个示例演示了当大家对三个无符号整数使用溢出加法(& )实行上溢运算时会发生如何:

    return vector

时时app平台注册网站 6V1

  }

        溢出减法 &-

func == (left: Vector, right: Vector) -> Bool { return left.x == right.x && left.y == right.y && left.z == right.z}

  数值溢出

            3.如:1 1111100,符号位为 1,表明那是一个负数,其余 7 个位则代表了数值 124(即 128 - 4)的二进制表示,结果是-(128-124) = -4

func - (vector: Vector) -> Vector { return Vector(x: -vector.x, y: -vector.y, z: -vector.z)}

  // unsignedOverflow 等于 UInt8 所能容纳的最大整数 255

var original = Vector2D(x: 1.0, y: 2.0)

    }

func - (left: Vector2D, right: Vector2D) -> Vector2D {

  let invertedBits = ~initialBits // 等于 0b11110000

    return vector

我们都领集会场合谓的运算符平时的也便是 - * / 之类的,比如大家随意写个 1 2 打字与印刷断定输出的是 3 ,那么大家为什么还要重载运算符呢?下边大家就比方,如下笔者定义个结构体

  按位与运算符

复合赋值运算符:将赋值运算符(=)与别的运算符举行组合。举个例子,将加法与赋值结合成加法赋值运算符( =)。在促成的时候,须求把运算符的左参数设置成 inout 类型,因为那个参数的值会在运算符函数内一贯被改变

prefix func - (vector: Vector) -> Vector { return Vector(x: -vector.x, y: -vector.y, z: -vector.z)}

  类和结构体可感觉依存的运算符提供自定义的兑现,那经常被喻为运算符重载。

    1.除了达成正式运算符,在 Swift 中还足以表明和落实自定义运算符

func   (left: Vector, right: Vector) -> Vector { return Vector(x: left.x   right.x, y: left.y   right.y, z: left.z   right.z)}

  ...

            2.别的因活动而超越整型存款和储蓄范围的位都会被遗弃。

时时app平台注册网站 7 V1 与 V2 的比较再来看看 > 的重载,逻辑稍微多一些

      return !(left == right)

/*高等运算符(Advanced Operators):位运算符、溢出运算符、优先级和结合性、运算符函数、自定义运算符

运转结果

  溢出也会发生在有记号整型数值上。

 

Tips:对于运算符的重载大家是无法重载 = 的,它是被编写翻译器固定具备的,在尾部它是与内部存款和储蓄器处理有关的,,我们不能够感到的去改变它,这里须要注意一下(可能您能够别把赋值运算 = 看成运算符 _ )。注意以下那几个标识=->///**/.<&??>!? 是被系统一保险留的。那么些标识无法被重载,也无法用于自定义运算符。

  然则,也足以选用让系统在数值溢出的时候利用截断管理,而非报错。能够选用swift 提供的八个溢出运算符来让系统帮衬整数溢出运算。那一个运算符都以以 & 开端的:

}

2 ** 2 ** 3

  为了选择等价运算符能对自定义的花色进行判等运算,须求为其提供自定义完结,完成的主意与另外中缀运算符同样:

let negative = -positive        // negative 是二个值为 (-3.0, -4.0) 的 Vector2D 实例

  • 2、含有三个参数的运算符的重载照着地点单目运算符的办法大家和好来写个 - 重载例子,如下

  复合赋值运算符将赋值运算符(=)与任何运算符实行重组。譬如,将加法与赋值结合成加法赋值运算符( =)。在贯彻的时候,须要把运算符的左参数设置成 inout 类型,因为那么些参数的值会在运算符函数内一贯被改造。

 

  • V2这里大家就曾经产生了 这一个运算符的重载。当然有意思味的童鞋还足以试着团结实现 - 或者 * 的重载,这里就不一一例如了。关于双目运算符的重载,和单目运算符类似,如下

    func = (left: inout Vector, right: Vector) { left = left right}

  }

 

prefix func     (vector: Vector) -> Vector { return Vector(x: vector.x   1, y: vector.y   1, z: vector.z   1)}

END

let outputBits = firstBits ^ otherBits // 等于 00010001

  • 2、自定义双目运算符双目运算符的概念和单目运算符的定义类似,不过双目运算符自定义的时候的器重字是 infix,如下

  extension Vector2D {

    1.对贰个数进行按位左移或按位右移,相当于对这一个数举行乘以 2 或除以 2 的演算。将七个整数左移一个人,等价于将那些数乘以 2,同样地,将多个偏分头右移一人,等价于将这些数除以 2。

return pow

  按位左移、右移运算符

let afterIncrement = toIncrement  // toIncrement 的值未来为 (4.0, 5.0), afterIncrement 的值同样为 (4.0, 5.0)

func > (left: Vector, right: Vector) -> Bool { if left.x != right.x { return left.x > right.x } if left.y != right.y { return left.y > right.y } if left.z != right.z { return left.z > right.z } //如果上面判断都失败了说明 left == right,所以返回值应该是 false return false}

    溢出加法 &

 

var V3 = Vector(x: 1, y: 1, z: 1)prefix operator    prefix func     (vector: Vector) -> Vector { return Vector(x: vector.x   1, y: vector.y   1, z: vector.z   1)}V3   

  我们毫不被预订义的演算符所限制。在 swift 中能够随意地定义中缀、前缀、后缀和赋值运算符。以及对应的优先级与结合性。那个运算符在代码中可以像预订义的运算符同样选用,大家居然足以扩张已有个别系列以支持自定义运算符。

    return Vector2D(x: left.x right.x, y: left.y - right.y)

  UInt8 类型的整数有 8 个比特位,能够积攒 0~255 之间的随机整数。那些事例初叶化了四个 UInt8 类型的莫西干发型,并赋值为二进制的 00001111,它的前四位都以 0,后 4 位都以 1。那几个值等价于十进制的 15。接着使用按位取反运算符创造了三个名称叫 invertedBits 的常量,这几个常量的值与总体按位取反后的 inteialBits 相等。即具备的 0 都变成了 1 ,同有的时候候具备的 1 都改成 0。invertedBits 的二进制值为 111一千0,等价于无符号十进制数的 240。

 

  那么些函数被定义成全局的,并不是 Vector2D 结构体的分子方法,所以随便四个 Vector2D 实例都足以选用那在那之中缀运算符。

func != (left: Vector2D, right: Vector2D) -> Bool {

  对于无符号与有号子整型数值来讲,当出现上溢时,它们会从数值所能容纳的最大数变成最小数。一样的,当产生下溢时,它们会从所能容纳的小小数成为最大的数。

 

  例子中定义了二个名称为 Vector2D 的结构体用来表示二维坐标向量(x, y),紧接着定义了贰个得以对四个 Vector2D 结构体实行相加运算符函数:

        如:prefix operator {}

  上边包车型的士例证展现了什么为自定义的结构体完毕加法运算符( )。算术运算符是贰个眼睛运算符,因为它能够对三个值举行演算,相同的时候它照旧中缀运算符,因为它出现在七个值中间。

struct Vector2D {

     }

let blueComponent = pink & 0x0000FF         // blueComponent 是 0x99,即 153

    var x = 0.0, y = 0.0

    1.位运算符能够操作数据结构中种种独立的比特位。它们平日被用在底层开垦中,比方图片编制程序和创办设备驱动。位运算符在管理外界能源的原本数据时也不行有用,举例对自定义通讯公约传输的数码开展编码和平解决码

  这段代码为 Vector2D 完成了单目负号运算符。由于该运算符是前缀运算符,所以那几个函数要求丰盛prefix 修饰符。

    1.也足以选取让系统在数值溢出的时候使用截断管理,而非报错。能够运用 Swift 提供的多少个溢出运算符来让系统援助整数溢出运算。那个运算符都是以 & 初叶的:

  prefix operator {}

func == (left: Vector2D, right: Vector2D) -> Bool {     //自定义等价运算符

  自定义运算符

 

  按位取反运算符

}

  为过大和过小的数值提供错误管理,能让我们管理边界值时更灵敏。

let initialBits: UInt8 = 0b00001111

  按位或运算符

    left = left right

      return Vector3D(x: -vector,x, y: -vector.y)

    2.要实现前缀恐怕后缀运算符,供给在宣称运算符函数的时候在 func 关键字从前线指挥部定 prefix 恐怕 postfix 修饰符

    }

}

  相比较无符号整数,有号子整数的运动运算相对复杂的多,这种复杂源于有标识整数的二进制展现情势。

var signedOverflow = Int8.min               // signedOverflow 等于 Int8 所能容纳的小不点儿整数 -128

  复合赋值运算符

let shiftBits: UInt8 = 4 // 即二进制的 00000100

  extension Vector2D {
    static prefix func (vector: inout Vector2D) -> Vector2D {
      vector = vector

let twoThree = Vector2D(x: 2.0, y: 3.0)

      return vector

按位异或运算符(^)能够对四个数的比特位实行比较。它回到三个新的数,当四个数的附和位差别等时,新数的附和位就为 1

  除了从前介绍过的着力运算符,swift 中还会有为数很多方可对数值实行复杂运算的高级级运算符。这个高等运算符包蕴了 C 和 OC 中已经被我们所谙习的位运算符和运动运算符。

        溢出加法 &

  }

let middleFourBits = firstSixBits & lastSixBits // 等于 00111100

  除了落到实处标准运算符,在 swift 中仍是能够申明和贯彻自定义运算符。

prefix operator {}      //必需先在全局功能域内进行定义

    static func  == (left: Vector2D, right: Vector2D) -> Bool {

    2.不可能对私下认可的赋值运算符(=)实行重载。唯有整合赋值运算符可以被重载。同样地,也力所比不上对三目条件运算符 (a ? b : c) 进行重载

  无符号整数的运动运算

    2.新的运算符要使用 operator 关键字在大局功能域内开展定义,同期还要钦定 prefix、infix 只怕 postfix 修饰符:

  前缀和后缀运算符

//=================

  按位异或运算符(^)能够对三个数的比特位实行相比较。它回到贰个新的数,当多个数的对应位不平等时,新数的附和位就为 1:

 

  运算符函数

var toIncrement = Vector2D(x: 3.0, y: 4.0)

  有暗号整数的位移运算

    1.结合性可取的值有left,right 和 none,非结合none运算符不能够跟其余同等优先级的演算符写在一块

  按位异或匀速符

}

  该运算符函数被定义为 Vector2D 上的三个类措施,况且函数的名字要与它要扩充重载的 名字一模二样。因为加法运算实际不是贰个向量须求的功能,所以这么些类情势被定义在 Vector2D 的二个扩展中,并非 Vector2D  结构体申明内。而算术加法运算符是眼睛运算符,所以这几个运算符函数收取多少个品种为 Vector2D 的参数,同一时间有一个 Vector2D 类型的再次来到值。

let firstSixBits: UInt8 = 0b11111100

  对无标识整数举办移动的平整如下:

if twoThree == anotherTwoThree {

  在暗中同意意况下,当向叁个整数赋予超越它的体量的值时,swift 暗中同意会报错,并不是生成二个没用的数。那几个行为为我们在运算过大和过小的数的时候提供了额外的安全性。

}

    static prefix func - (vector: Vector2D) -> Vector2D {

//高等运算符

      return (left.x == reght.x) && (left.y == right.y)

按位与运算符(&)能够对八个数的比特位进行统一。它回到一个新的数,唯有当多个数的照顾位都为 1 的时候,新数的应和位才为 1

  }
  extension Vector2D {

let vectorToAdd = Vector2D(x: 3.0, y: 4.0)

  数值有非常大恐怕出现上溢恐怕下溢。

 

  // unsignedOverflow 等于 UInt8 所能容纳的细小整数 0

    3.

    任何因移动而超过整型存款和储蓄范围的位都会被放弃

let afterDoubling = toBeDoubled      // toBeDoubled 今后的值为 (2.0, 8.0), afterDoubling 以往的值也为 (2.0, 8.0)

    }

unsignedOverflow = unsignedOverflow &- 1    // 此时 unsignedOverflow 等于 255

    用 0 来填充移位后发生的空白位

        unsignedOverflow = unsignedOverflow & 1    // 此时 unsignedOverflow 等于 0

  swift   补助 C 语言中的全部位运算符,接下去会相继介绍。

let positive = Vector2D(x: 3.0, y: 4.0)

  自定义结构体、类和枚举时,假设也为它们提供正规 swift 运算符的兑现,将会万分实用。在 swift 中自定义运算符非常轻巧,运算符也会针对不一致品种应用相应实现。

let combinedbits = someBits | moreBits // 等于 11111110

  优先级和结合性

运算符函数:

    static func (left: inout Vector2D, right: Vector2D) -> Vector2D {
      return Vector2D(x: left.x right.x, y: left.y right.y)

 

  自定义的类和结构体未有对等价运算符进行暗许完结,等价运算符常常被称为 "相等" 运算符(==)与 “不等” 运算符(!=)。对于自定义类型,swift 无法料定其是还是不是 “相等”,因为 “相等” 的意义取决于这个自定义的体系在您的代码中所扮演的剧中人物。

shiftBits << 2           // 00010000

 

 

prefix func (inout vector: Vector2D) -> Vector2D {

let firstBits: UInt8 = 0b00010100

 

prefix func (inout vector: Vector2D) -> Vector2D {

let vector = Vector2D(x: 3.0, y: 1.0)

 

 

    1.类和结构体可认为现有的运算符提供自定义的完结,这一般被称之为运算符重载

    vector = Vector2D(x: 1.0, y: 1.0)

溢出运算符:在暗许意况下,当向贰个板寸赋予抢先它体积的值时,斯威夫特默许会报错,实际不是生成二个无效的数

 

        1.对无标识整数进行运动的平整如下:

}

            4.一旦想对七个Int8举办加法运算,大家只供给将那多个数的任何 8 个比特位实行相加,何况将计算结果中中国足球球联赛出 8 位的数值丢掉

        var unsignedOverflow = UInt8.max    // unsignedOverflow 等于 UInt8 所能容纳的最大整数 255

let alsoPositive = -negative    // alsoPositive 是二个值为 (3.0, 4.0) 的 Vector2D 实例

//=================

            5.当对正整数举办按位右移运算时,服从与无符号整数同样的平整,但是对于运动发生的空白位使用标记位实行填充,并不是用 0

自定义运算符:

单近期缀和后缀运算符、双目中缀运算符:

var unsignedOverflow = UInt8.min            // unsignedOverflow 等于 UInt8 所能容纳的一丁点儿整数 0

    print("These two vectors are equivalent.")

func = (inout left: Vector2D, right: Vector2D) {

infix operator - { associativity left precedence 140 }

按位或运算符(|)能够对四个数的比特位进行相比较。它回到贰个新的数,只要五个数的附和位中有私下四个为 1 时,新数的呼应位就为 1

    return Vector2D(x: left.x right.x, y: left.y right.y)

            3.用 0 来填充移位后产生的空白位。

    return (left.x == right.x) && (left.y == right.y)

original = vectorToAdd         // original 的值未来为 (4.0, 6.0)

位运算符:

 

var toBeDoubled = Vector2D(x: 1.0, y: 4.0)

 

let moreBits: UInt8 = 0b01011110

prefix func - (vector: Vector2D) -> Vector2D {

            1.有标识整数使用第 1 个比特位(通常被称之为符号位)来代表这么些数的正负。符号位为 0 代表正数,为 1 代表负数,别的的比特位(平常被喻为数值位)存款和储蓄了实际上的值。有暗记正整数和无符号数的积存形式是平等的,都以从 0 开头算起

    var x = 0.0, y = 0.0

    return Vector2D(x: -vector.x, y: -vector.y)

func (left: Vector2D, right: Vector2D) -> Vector2D {

signedOverflow = signedOverflow &- 1        // 此时 signedOverflow 等于 127

本文由时时app平台注册网站发布于编程知识,转载请注明出处:重读 Swift 之二:Operator Declaration(运算符重载)

关键词: