overloading + and += operators for “Number Classes”

前端 未结 4 839
野性不改
野性不改 2021-02-08 14:45

I want to create extension functions for classes that encapsulate simple Numbers. For example DoubleProperty. I encountered the problem, that I can\'t

4条回答
  •  难免孤独
    2021-02-08 15:19

    Your operator override implementation has two problems:

    1. inconsistent type after plus

    operator fun ObservableDoubleValue.plus(number: Number): DoubleProperty 
        = SimpleDoubleProperty(get() + number.toDouble())
    

    Any ObservableDoubleValue instance plus a Number, got a DoubleProperty instance(or say a SimpleDoubleProperty instance). Let's say I have a type ComplexDoubleProperty implements ObservableDoubleValue, you will see:

    var a = getComplexDoubleProperty()
    a = a + 0.1    //compile error, WTF?
    
    //or even
    var b = SimpleDoubleProperty(0.1)
    b = b + 0.1    //compile error, because b+0.1 is DoubleProperty
    

    You can see this behavior makes no sense.

    2. a=a+b and a+=b should be identical

    If your implementation compiles, you will have

    var a: DoubleProperty = SimpleDoubleProperty(0.1)  //add DoubleProperty to make it compile
    var b = a
    a += 0.1
    println(b == a)
    

    prints true because += sets the value to the original instance. If you replace a+=0.1 with a=a+0.1 you will get false because a new instance is returned. Generally speaking, a=a+b and a+=b are not identical in this implementation.

    To fix the two problems above, my suggestion is

    operator fun SimpleDoubleProperty.plus(number: Number): SimpleDoubleProperty
            = SimpleDoubleProperty(get() + number.toDouble())
    

    so you don't need to override plusAssign. The solution is not as general as yours, but it's correct if you only have SimpleDoubleProperty calculations, and I believe you do, because in your implementation, plus always returns a SimpleDoubleProperty instance.

提交回复
热议问题