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

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

下面是示例类。 在这种情况下,如何检测年龄或名称更改的时间?

data class Person(var Name: String, var Age: Int) 

所以如果有人有任何想法,请帮助。

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

数据类真的不是为了这个。 由于它们的属性必须在主构造函数中声明,所以不能真正向它们添加自定义行为。

这就是说,如果你必须的话,你可以通过复制属性来实现这一点,然后使用自定义设置器或Delegates.observable

这里有一个方法可以用自定义设置器来完成,在这里你将访问公开可见的nameage属性,这些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 } } 

同样的想法,用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 } } 

使用这些看起来像这样( 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 

编辑回答下面的问题:

如果你不需要你的类是一个数据类,下面可能是最简单的解决方案:

 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") } } 

这样,你仍然有一个构造函数,它将参数的名字和年龄作为参数,但是它们被分配给类的内部的属性。 对于数据类来说这是不可能的,因为数据类的每个构造函数参数都必须是一个属性(标记为valvar )。 更多的,你可以看到关于构造函数 , 属性和数据类的文档。

委托属性

有一些常见的属性,虽然我们可以在需要的时候手动实现,但是一劳永逸的实现,并将其放到一个库中是非常好的。 例子包括

延迟属性:只在第一次访问时计算值,可观察属性:侦听器将获得关于此属性更改的通知,将属性存储在映射中,而不是每个属性的单独字段。 为了涵盖这些(和其他)情况,Kotlin支持委托属性:

 class Example { var p: String by Delegate() } 

语法是:val / var:by。 之后的expression式是委托,因为对应于该属性的get()(和set())将委托给它的getValue()和setValue()方法。 属性委托不必实现任何接口,但他们必须提供一个getValue()函数(和setValue() – var的)。 例如:

 class Delegate { operator fun getValue(thisRef: Any?, property: KProperty<*>): String { return "$thisRef, thank you for delegating '${property.name}' to me!" } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { println("$value has been assigned to '${property.name} in $thisRef.'") } }