如何为KMutableProperty参数赋值?

时间:2016-06-10 15:29:38

标签: kotlin

在一个方法中,我希望接收KMutableProperty作为参数并为其赋值。

另一个问题是将参数传递给这种方法的正确方法是什么。

基本上我想有类似的东西:

class MyBinder {
  ...

  fun bind(property: KMutableProperty<Int>): Unit {
     property.set(internalIntValue)
  }
}

然后在另一个班级中调用它

  myBinder.bind(this::intProperty)

2 个答案:

答案 0 :(得分:5)

Kotlin 1.0不允许使用this::intProperty语法,但目前正在使用它,并且很快就可以作为1.1的早期访问预览的一部分(issueKEEP proposal

考虑到这一点,我考虑以另一种方式做你正在描述的事情,例如让bind接受设置属性的lambda:

class MyBinder {
    fun bind(setProperty: (Int) -> Unit) {
        setProperty(internalIntValue)
    }
}

...

myBinder.bind { intProperty = it }

无论如何,要回答关于设置KMutableProperty的值的问题:设置某个属性的值,或者从技术上讲,调用属性设置器,你应该知道它的arity或参数的数量property(及其getter / setter)接受。在文件中声明的属性不接受任何参数,成员属性和扩展属性需要一个参数(接收器实例),而也是扩展的成员属性需要两个参数。这些类型的属性分别由KMutableProperty的以下子类型表示:KMutableProperty0KMutableProperty1KMutableProperty2 - 数字表示arity及其泛型类型参数表示类型接收者这些属性类型中的每一个都具有set方法以及相应的参数。一些例子:

fun setValue(property: KMutableProperty0<Int>, value: Int) {
    property.set(value)
}

fun setValue(property: KMutableProperty1<SomeType, Int>, instance: SomeType, value: Int) {
    property.set(instance, value)
}

请注意,抽象set界面中没有get(或KMutableProperty)方法,因为它无法声明,不知道数字所需的接收器参数。

答案 1 :(得分:0)

除了亚历山大的回答,你可以尝试这样的事情:

import kotlin.reflect.KMutableProperty

class Binder {
  val internalIntValue = 10

  fun bind(self: Any, aProperty: KMutableProperty<Int>) {
    aProperty.setter.call(self, internalIntValue)
  }
}

class Foo {
  var bar = 1

  fun changeBar() {
    Binder().bind(this, Foo::bar)
  }
}

fun main(args: Array<String>) {
  val foo = Foo()

  assert(1 == foo.bar)

  foo.changeBar()

  assert(10 == foo.bar)
}

更健壮/更安全的方式来做同样的事情:

fun <T> bind(self: T, aProperty: KMutableProperty1<T, Int>) {
  aProperty.set(self, internalIntValue)
}

我要感谢亚历山大。他的回答给了我以前的想法。