overloading + and += operators for “Number Classes”

前端 未结 4 776
别那么骄傲
别那么骄傲 2021-02-08 11:56

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 12:25

    The strange += operator in Kotlin

    you can both overloading the plus operator and plusAssign operator in kotlin, but you must following the rules of kotlin to solving the strange += conflicts.

    1. introduce an immutable structure of the class for the plus operator which means any class outside the class can't edit its internal data.

    2. introduce a mutable structure of the class for the plusAssign operator which means its internal data can be edited anywhere.

    the kotlin has already done such things in the stdlib for the Collection & the Map classes, the Collection#plus and MutableCollection#plusAssign as below:

    operator fun  Collection.plus(elements: Iterable): List
    //                   ^--- immutable structure
    
    operator fun  MutableCollection.plusAssign(elements: Iterable)
    //                   ^--- mutable structure
    

    But wait, how to solving the conflict when we using the += operator?

    IF the list is an immutable Collection then you must define a mutable var variable, then the plus operator is used since its internal state can't be edited. for example:

    //         v--- define `list` with the immutable structure explicitly  
    var list: List = arrayListOf(1);   //TODO: try change `var` to `val`
    val addend = arrayListOf(2);
    val snapshot = list;
    
    list += addend;
    //   ^--- list = list.plus(addend);
    //  list = [1, 2], snapshot=[1], addend = [2]
    

    IF the list is a mutable MutableCollection then you must define a immutable val variable, then the plusAssign operator is used since its internal state can be edited anywhere. for example:

    //    v--- `list` uses the mutable structure implicitly
    val list = arrayListOf(1); //TODO: try change `val` to `var`
    val addend = arrayListOf(2);
    val snapshot = list;
    
    list += addend;
    //   ^--- list.plusAssign(addend);
    //  list = [1, 2], snapshot=[1, 2], addend = [2]
    

    On the other hand, you can overloads an operator with diff signatures, each signature for the different context, and kotlin also do it, e.g: Collection#plus. for example:

    var list = listOf();
    
    list += 1; //list = [1];
    //   ^--- list = list.plus(Integer);
    
    list += [2,3]; //list = [1, 2, 3]
    //   ^--- list = list.plus(Iterable);
    

提交回复
热议问题