小跑青年 發表於 2023-7-7 10:49:16

Swift之运算符重载示例详解

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>引言</li><li>重载双目运算符</li><li>单目运算符</li><li>复合赋值运算符</li><li>等价运算符 ==</li><li>自定义运算符</li><ul class="second_class_ul"><li>自定义后置运算符</li><li>自定义中置运算符</li></ul></ul></div><p class="maodian"></p><h2>引言</h2>
<p>在C++中, 运算符是可以重载的, Swift也是支持的</p>
<p>注:<code>=</code>和三目运算符<code>a ? b : c</code>不可重载</p>
<p class="maodian"></p><h2>重载双目运算符</h2>
<div class="jb51code"><pre class="brush:cpp;">class Vector {
    var x: Double = 0.0
    var y: Double = 0.0
    var z: Double = 0.0
    init(x: Double, y: Double, z: Double) {
      self.x = x
      self.y = y
      self.z = z
    }
    convenience init() {
      self.init(x: 0, y: 0, z: 0)
    }
    /// Operator '+' declared in type 'Vector' must be 'static'
    /// + 是双目运算符,两个参数
    static func +(v1: Vector, v2: Vector) -&gt; Vector {
      let vector: Vector = Vector()
      vector.x = v1.x + v2.x
      vector.y = v1.y + v2.y
      vector.z = v1.z + v2.z
      return vector
    }
}</pre></div>
<p class="maodian"></p><h2>单目运算符</h2>
<p>类和结构体也可以实现单目运算符,单目运算符只运算一个值。</p>
<p>运算符出现在值之前为前缀运算符(prefix, 如 -a),出现在值之后为后缀运算符(postfix, 如a!)。</p>
<div class="jb51code"><pre class="brush:cpp;">struct Coordinate {
    var x: Double = 0.0
    var y: Double = 0.0
    static prefix func +(coordinate: Coordinate) -&gt; Coordinate {
      return Coordinate(x: +coordinate.x, y: +coordinate.y)
    }
    static prefix func -(coordinate: Coordinate) -&gt; Coordinate {
      return Coordinate(x: -coordinate.x, y: -coordinate.y)
    }
}
func test() {
    let p1 = Coordinate(x: 1.0, y: 1.0)
    let p2 = Coordinate(x: 2.0, y: 2.0)
    print(-p1) // Coordinate(x: -1.0, y: -1.0)
    print(+p2) // Coordinate(x: 2.0, y: 2.0)
}</pre></div>
<p class="maodian"></p><h2>复合赋值运算符</h2>
<p>复合赋值运算符是赋值运算符(=)和其他运算符进行结合, 如 +=、-=</p>
<div class="jb51code"><pre class="brush:cpp;">struct Coordinate {
    var x: Double = 0.0
    var y: Double = 0.0
    // 如果放在全局函数里, 不需要加static, 否则, static不可省略
    static func +=(left: inout Coordinate, right: Coordinate) {
      left = Coordinate(x: left.x + right.x, y: left.y + right.y)
    }
    static func -=(c1: inout Coordinate, c2: Coordinate) {
      left = Coordinate(x: left.x - right.x , y: left.y - right.y)
    }
}
func test() {
    var p1 = Coordinate(x: 1.0, y: 1.0)
    let p2 = Coordinate(x: 2.0, y: 2.0)
    p1 += p2
    print(p1) // Coordinate(x: 3.0, y: 3.0)
}</pre></div>
<p class="maodian"></p><h2>等价运算符 ==</h2>
<p>自定义类和结构体没有对等价运算符进行默认的实现。等价运算符一般被称为相等运算符<code>==</code>和不等运算符 <code>!=</code></p>
<div class="jb51code"><pre class="brush:cpp;">struct Coordinate {
    var x: Double = 0.0
    var y: Double = 0.0
    static func ==(c1: Coordinate, c2: Coordinate) -&gt; Bool {
      return c1.x == c2.x &amp;&amp; c1.y == c2.y
    }
    static func !=(left: Coordinate, right: Coordinate) -&gt; Bool {
      return left.x != right.x || left.y != right.y
    }
}
func test() {
    let p1 = Coordinate(x: 1.0, y: 1.0)
    var p2 = Coordinate(x: 2.0, y: 2.0)
    print(p1 == p2) // false
    p2.x -= 1
    p2.y -= 1
    print(p1 == p2) // true
}</pre></div>
<p class="maodian"></p><h2>自定义运算符</h2>
<p>可以自定义前置运算符prefix、后置运算符postfix、中置运算符infix, 约束条件:</p>
<ul><li>只能使用如下字符:<br /><code>- + * / = % &lt; &gt; ! &amp; | ^ . ~</code></li><li>只有中置运算符可以继承优先级组 precdence(后面介绍)</li><li>自定义运算符不可放在类中,必须放在文件作用域中</li></ul>
<p class="maodian"></p><h3>自定义后置运算符</h3>
<div class="jb51code"><pre class="brush:cpp;">struct Coordinate {
    var x: Double = 0.0
    var y: Double = 0.0
}
// 文件作用域,即全局作用域,不可在class下
prefix operator +++
prefix func +++(coordinate: inout Coordinate) -&gt; Coordinate {
    coordinate.x = coordinate.x + coordinate.x
    coordinate.y = coordinate.y + coordinate.y
    return coordinate
}
func test() {
    var p1 = Coordinate(x: 1.0, y: 1.0)
    print(+++p1) // Coordinate(x: 2.0, y: 2.0)
}</pre></div>
<p>自定义前置运算符和自定义后置运算符类似</p>
<div class="jb51code"><pre class="brush:cpp;">postfix operator +++
postfix func +++(coordinate: inout Coordinate) -&gt; Coordinate {
    coordinate.x = coordinate.x + coordinate.x
    coordinate.y = coordinate.y + coordinate.y
    return coordinate
}</pre></div>
<p class="maodian"></p><h3>自定义中置运算符</h3>
<div class="jb51code"><pre class="brush:cpp;">precedencegroup MyPrecedence {
    // higherThan: AdditionPrecedence   // 优先级, 比加法运算高
    lowerThan: AdditionPrecedence       // 优先级, 比加法运算低
    associativity: none               // 结合方向:left, right or none
    assignment: false                   // true代表是赋值运算符,false代表非赋值运算符
}
infix operator +++ : MyPrecedence// 继承 MyPrecedence 优先级组(可选)
func +++(left: Int, right: Int) -&gt; Int {
    return (left + right) * 2
}
func test() {
    print(3+++2)
}</pre></div>
<p>借助自定义运算符,我们可以浪一浪,定义一个操作符,当有值是使用此值,无值时使用想要的默认值,如下所示:</p>
<div class="jb51code"><pre class="brush:cpp;">postfix operator &lt;&lt;&lt;
postfix func &lt;&lt;&lt;(a: String?) -&gt; String { return a ?? "" }
func test() {
    print(getStr()&lt;&lt;&lt;)
}
func getStr() -&gt; String? {
    return nil
}</pre></div>
<p>示例</p>
<div class="jb51code"><pre class="brush:cpp;">postfix operator &lt;&lt;&lt;
postfix func &lt;&lt;&lt;(a: String?)            -&gt; String            { return a ?? "" }
postfix func &lt;&lt;&lt;(a: Int?)               -&gt; Int               { return a ?? 0 }
postfix func &lt;&lt;&lt;(a: Int8?)                -&gt; Int8                { return a ?? 0 }
postfix func &lt;&lt;&lt;(a: Int16?)               -&gt; Int16               { return a ?? 0 }
postfix func &lt;&lt;&lt;(a: Int32?)               -&gt; Int32               { return a ?? 0 }
postfix func &lt;&lt;&lt;(a: Int64?)               -&gt; Int64               { return a ?? 0 }
postfix func &lt;&lt;&lt;(a: UInt?)                -&gt; UInt                { return a ?? 0 }
postfix func &lt;&lt;&lt;(a: Double?)            -&gt; Double            { return a ?? 0.0 }
postfix func &lt;&lt;&lt;(a: Float?)               -&gt; Float               { return a ?? 0.0 }
postfix func &lt;&lt;&lt;(a: ?)         -&gt;          { return a ?? [] }
postfix func &lt;&lt;&lt;(a: ?)            -&gt;             { return a ?? [] }
postfix func &lt;&lt;&lt;(a: ?)               -&gt;                { return a ?? [] }
postfix func &lt;&lt;&lt;(a: ?) -&gt; { return a ?? [:]}
postfix func &lt;&lt;&lt;(a: ?)    -&gt;     { return a ?? [:] }</pre></div>
<p>以上就是Swift之运算符重载示例详解的详细内容,更多关于Swift运算符重载的资料请关注琼殿技术社区其它相关文章!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>Swift 重构重载运算符示例解析</li><li>Swift重构自定义空等运算符&nbsp;“??=”&nbsp;实例</li><li>iOS Swift逻辑运算符示例总结</li><li>swift中自定义正则表达式运算符=~详解</li><li>Swift心得笔记之运算符</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: Swift之运算符重载示例详解