如何检测Data class Kotlin中更改的值?

juj*_*uzi 10 android kotlin

我想检测我的类的属性更改的任何值,然后我可以在那之后做另一个操作.换句话说,如果属性的某个特定数据发生了变化,那么特定事件将在此时触发.实际上,如果它是其他编程语言(如Java)中的普通类,那么我认为在数据修改或在C#中使用委托后我可以使用setter来完成这项工作.但由于Kotlin很新,我根本找不到任何解决方案.我试图超载财产,但任何机会都没有成功.我也想使用接口,但是因为它是数据类,所以我不知道应该怎么做.

以下是示例类.在这种情况下,如何检测Age或名称何时更改?

data class Person(var Name: String, var Age: Int) 
Run Code Online (Sandbox Code Playgroud)

所以,如果有人对此有任何想法,请帮助.

注意:在我的情况下,必须使用数据类.

zsm*_*b13 15

数据类实际上并不是为此而做的.由于必须在主构造函数中声明它们的属性,因此无法为它们添加自定义行为.

也就是说,如果必须,您可以通过复制属性,然后使用自定义setter或者来实现此目的Delegates.observable.

这里是一种自定义setter方法做到这一点,在这里你会被访问的公开可见的nameage属性,保留在构造函数中最新的以及宣布的:

data class Person(private var _name: String, private var _age: Int) {

    var name = _name
        set(value) {
            println("Name changed from $name to $value")
            field = value // sets the backing field for `name`
            _name = value // sets the `_name` property declared in the primary ctor
        }

    var age = _age
        set(value) {
            println("Age changed from $age to $value")
            field = value
            _age = value
        }

}
Run Code Online (Sandbox Code Playgroud)

同样的想法,有Delegates.observable一些为你做的工作,这里你唯一的开销是将构造函数中声明的属性设置为新值:

data class Person(private var _name: String, private var _age: Int) {

    var name: String by Delegates.observable(_name) { prop, old, new ->
        println("Name changed from $old to $new")
        _name = new
    }

    var age: Int by Delegates.observable(_age) { prop, old, new ->
        println("Age changed from $old to $new")
        _age = new
    }

}
Run Code Online (Sandbox Code Playgroud)

使用其中任何一个都是这样的(toString使用下划线看起来有点难看):

val sally = Person("Sally", 50)
println(sally)      // Person(_name=Sally, _age=50)
sally.age = 51      // Age changed from 50 to 51
println(sally)      // Person(_name=Sally, _age=51)
println(sally.name) // Sally
println(sally.age)  // 51
Run Code Online (Sandbox Code Playgroud)

编辑以回答以下问题:

如果您不需要将您的类作为数据类,则以下可能是最简单的解决方案:

class Person(name: String, age: Int) {

    var name: String by Delegates.observable(name) { _, old, new ->
        println("Name changed from $old to $new")
    }

    var age: Int by Delegates.observable(age) { _, old, new ->
        println("Age changed from $old to $new")
    }

}
Run Code Online (Sandbox Code Playgroud)

这样,您仍然有一个构造函数,它将name和age作为参数,但它们会被分配给类主体内的属性.对于数据类,这是不可能的,因为数据类的每个构造函数参数也必须是属性(标记为valvar).有关更多信息,您可以查看有关构造函数,属性数据类的文档.