Home > Blockchain >  Call super of infix operator
Call super of infix operator

Time:09-27

I'm trying to call super. = operator, but I get a compiler error. I looked for the correct syntax / way to do it without success.

If we have, for instance

class a {
  var item1: Int

  static func  = (left: inout a, right: a) {left.item1  = right.item1;}
}

class b : a {
  var item2 : Int;
  
  static func  = (left: inout b, right: b) {  
    super. =(left: left as a, right: right as a)  <-- compile issue
    left.item2  = right.item2;
  }
}

Can someone please point out the correct syntax for this to work? Thank you

CodePudding user response:

Operators are statically dispatched (see how they are marked static?) That means they are dispatched solely based on the compile-time types of the operands. Operators don't override each other like instance methods do, and so there is no need to call super.

If the operands' compile-time type are the super type, then the super type's operator will be called.

In this case, just casting right to A suffices, because B's operator cannot be called with an A as its second operand.

Another thing is that you don't need the first operands to be inout, because these are classes, not structs. Only value type parameters, like structs, need inout in order for you to modify their values inside the operator function.

Having the copy-in-copy-out semantic of inout present here will make it a lot harder to call from the subclass.

Here's the code with everything fixed:

class A {
    var item1: Int
    
    init(item1: Int) {
        self.item1 = item1
    }

    static func  = (left: A, right: A) { left.item1  = right.item1 }
}

class B : A {
    var item2 : Int
    
    init(item1: Int, item2: Int) {
        self.item2 = item2
        super.init(item1: item1)
    }
  
    static func  = (left: B, right: B) {
        left  = right as A
        left.item2  = right.item2;
    }
}

let x = B(item1: 2, item2: 3)
let y = B(item1: 1, item2: 1)
x  = y
print(x.item1, x.item2) // 3 4
print(y.item1, y.item2) // 1 1

Note that it is possible to do:

let x = B(item1: 2, item2: 3)
let y: A = B(item1: 2, item2: 3)
x  = y

and x would have item1: 4, item2: 3.This is because operators are dispatched statically, based on compile time types. If that is undesirable, perhaps don't put operators on non-final classes.

  • Related