Jho*_*007 9 operator-overloading kotlin extension-function
我想为封装简单Numbers的类创建扩展函数.例如DoubleProperty.我遇到了问题,我不能同时超载+和+=操作员.
我不想创建一个通过以下测试的行为:
class DoublePropertyTest {
lateinit var doubleProperty: DoubleProperty
@Before
fun initialize() {
doubleProperty = SimpleDoubleProperty(0.1)
}
@Test
fun plus() {
val someProperty = doubleProperty + 1.5
assertEquals(someProperty.value, 1.6, 0.001)
}
@Test
fun plusAssign() {
val someProperty = doubleProperty
doubleProperty += 1.5 //error if + and += are overloaded
assert(someProperty === doubleProperty) //fails with only + overloaded
assertEquals(doubleProperty.value, 1.6, 0.001)
}
}
Run Code Online (Sandbox Code Playgroud)
它可以使用这些扩展函数实现:
operator fun ObservableDoubleValue.plus(number: Number): DoubleProperty
= SimpleDoubleProperty(get() + number.toDouble())
operator fun WritableDoubleValue.plusAssign(number: Number)
= set(get() + number.toDouble())
Run Code Online (Sandbox Code Playgroud)
问题是,如果+是过度的,那么+=也不能过载:
Assignment operators ambiguity. All these functions match.
- public operator fun ObservableDoubleValue.plus(number: Number): DoubleProperty
- public operator fun WritableDoubleValue.plusAssign(number: Number): Unit
Run Code Online (Sandbox Code Playgroud)
如果我只重载+操作符,DoubleProperty则在+=操作上返回一个新对象而不是初始对象.
有办法解决这个限制吗?
+=Kotlin 的奇怪操作员你可以在kotlin中重载plus运算符和plusAssign运算符,但是你必须遵循kotlin的规则来解决奇怪的+=冲突.
为运算符引入类的不可变结构,
plus这意味着类外的任何类都无法编辑其内部数据.为操作符引入类的可变结构,
plusAssign这意味着它的内部数据可以在任何地方编辑.
kotlin已经在stdlibfor Collection&Mapclasses中完成了这些事情,Collection#plus和MutableCollection#plusAssign如下:
operator fun <T> Collection<T>.plus(elements: Iterable<T>): List<T>
// ^--- immutable structure
operator fun <T> MutableCollection<in T>.plusAssign(elements: Iterable<T>)
// ^--- mutable structure
Run Code Online (Sandbox Code Playgroud)
+=运营商时如何解决冲突呢?如果列表是不可变的,Collection那么你必须定义一个可变var变量,然后使用plus运算符,因为它的内部状态不能被编辑.例如:
// v--- define `list` with the immutable structure explicitly
var list: List<Int> = 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]
Run Code Online (Sandbox Code Playgroud)
如果列表是可变的,MutableCollection那么你必须定义一个不可变的val变量,然后使用plusAssign运算符,因为它的内部状态可以在任何地方编辑.例如:
// 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]
Run Code Online (Sandbox Code Playgroud)
另一方面,您可以使用diff签名重载操作符,每个签名用于不同的上下文,kotlin也可以执行此操作,例如:Collection#plus.例如:
var list = listOf<Int>();
list += 1; //list = [1];
// ^--- list = list.plus(Integer);
list += [2,3]; //list = [1, 2, 3]
// ^--- list = list.plus(Iterable);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2968 次 |
| 最近记录: |