Kotlin MutableMap getter和setter未按预期工作
在一个类中,我有一个Kotlin MutableMap getter和setter未按预期工作,kotlin,operator-overloading,Kotlin,Operator Overloading,在一个类中,我有一个MutableMap,我想声明一个getter和一个setter,如下所示: open class StringList() { private val list= mutableListOf<String>() var values: MutableMap<String, String> get() { println("get member") // this is printe
MutableMap
,我想声明一个getter和一个setter,如下所示:
open class StringList() {
private val list= mutableListOf<String>()
var values: MutableMap<String, String>
get() {
println("get member") // this is printed.. twice
return mutableMapOf<String, String>()
}
set(value) {
println("set member") // this is not printed
}
fun add(s: String, aObject: Any? = null): Int {
list.add(s)
return list.count() - 1
}
}
我意识到执行是两次给getter,而不是setter
我做错了什么 几天前,我用
列表回答了一个类似的问题,而不是用可变地图回答了一个类似的问题,请参见
这是带有MutableMap
class MMap<T, U>(
private val map: MutableMap<T, U> = mutableMapOf(),
private val getter: ((T) -> Unit)? = null,
private val setter: ((U) -> Unit)? = null
) : MutableMap<T, U> by map {
override fun put(key: T, value: U): U? =
map.put(key, value).also { setter?.invoke(value) }
override fun get(key: T): U? =
map[key].also { getter?.invoke(key) }
}
class-MMap(
私有val映射:MutableMap=mutableMapOf(),
private val getter:((T)->Unit)?=null,
专用val设置器:((U)->单位)?=null
):可变映射逐映射{
覆盖有趣的put(键:T,值:U):U?=
map.put(key,value).也是{setter?.invoke(value)}
覆盖乐趣获取(键:T):U?=
映射[key]。也是{getter?.invoke(key)}
}
用法:
var values = MMap<String, String>(
getter = { println("get member $it") },
setter = { println("set member $it") }
)
var值=MMap(
getter={println(“get member$it”)},
setter={println(“set成员$it”)}
)
几天前,我用列表回答了一个类似的问题,而不是可变地图
看到了吗
这是带有MutableMap
class MMap<T, U>(
private val map: MutableMap<T, U> = mutableMapOf(),
private val getter: ((T) -> Unit)? = null,
private val setter: ((U) -> Unit)? = null
) : MutableMap<T, U> by map {
override fun put(key: T, value: U): U? =
map.put(key, value).also { setter?.invoke(value) }
override fun get(key: T): U? =
map[key].also { getter?.invoke(key) }
}
class-MMap(
私有val映射:MutableMap=mutableMapOf(),
private val getter:((T)->Unit)?=null,
专用val设置器:((U)->单位)?=null
):可变映射逐映射{
覆盖有趣的put(键:T,值:U):U?=
map.put(key,value).也是{setter?.invoke(value)}
覆盖乐趣获取(键:T):U?=
映射[key]。也是{getter?.invoke(key)}
}
用法:
var values = MMap<String, String>(
getter = { println("get member $it") },
setter = { println("set member $it") }
)
var值=MMap(
getter={println(“get member$it”)},
setter={println(“set成员$it”)}
)
之所以发生这种情况,是因为变量的setter
在其内容发生更改时不会被调用,而只有在存在分配时才会被调用,而且在您的情况下,您从未分配过它
var sl=StringList()
//不调用setter。
sl.add(“用户=amo”)
//.values调用getter。
sl.values[“用户”]=“其他”
//.values再次调用getter。
val r=sl.values[“用户”]
//在进行赋值后调用setter(这一行只是关于如何调用setter的示例)。
sl.values=mutableMapOf()
之所以发生这种情况,是因为变量的setter
在其内容发生更改时不会被调用,而只有在存在分配时才会被调用,而且在您的情况下,您从未分配过它
var sl=StringList()
//不调用setter。
sl.add(“用户=amo”)
//.values调用getter。
sl.values[“用户”]=“其他”
//.values再次调用getter。
val r=sl.values[“用户”]
//在进行赋值后调用setter(这一行只是关于如何调用setter的示例)。
sl.values=mutableMapOf()
好的,我想我明白你想做什么。您希望在添加值或从可变映射检索值时发生一些副作用,对吗
属性的getter和setter与此无关。它们是属性的getter和setter,是对可变映射的引用。它们不是映射本身中值的获取者和设置者
您可以使用两种不同的策略来实现此目的:
1) 创建您自己的具有副作用的map类。实现这一点最简单的方法是通过对现有的可变映射实现(如HashMap)进行子类化
open class StringList() {
private val list = mutableListOf<String>()
val values = object: HashMap<String, String>(){
override fun get(key: String): String? {
println("Retrieved map value for key $key") // Side effect here
return super.get(key)
}
override fun put(key: String, value: String): String? {
println("Put key value pair $key / $value") // Side effect here
return super.put(key, value)
}
}
//...
}
好吧,我想我明白你想做什么。您希望在添加值或从可变映射检索值时发生一些副作用,对吗
属性的getter和setter与此无关。它们是属性的getter和setter,是对可变映射的引用。它们不是映射本身中值的获取者和设置者
您可以使用两种不同的策略来实现此目的:
1) 创建您自己的具有副作用的map类。实现这一点最简单的方法是通过对现有的可变映射实现(如HashMap)进行子类化
open class StringList() {
private val list = mutableListOf<String>()
val values = object: HashMap<String, String>(){
override fun get(key: String): String? {
println("Retrieved map value for key $key") // Side effect here
return super.get(key)
}
override fun put(key: String, value: String): String? {
println("Put key value pair $key / $value") // Side effect here
return super.put(key, value)
}
}
//...
}
也许我误解了,但你从来没有打电话给二传手,你打了两次电话给二传手。调用setter应该是s1.values=mutableMapOf etc,但是您两次引用s1.values作为getter,第一次是设置一个条目位而不是设置映射可能我误解了,但是您从来没有调用setter,您调用getter两次。调用setter将是s1.values=mutableMapOf etc,但您将s1.values作为getter引用了两次,第一次设置一个条目位时没有设置映射,因此不可能使用这种语法sl.values[“user”]=“other”
来触发setter??否,我认为你对能手和二传手的工作有一个基本的误解。setter更改mapsl
的值。如果不向setter传递新值,则无法触发setter。在这种情况下,新值将是一个全新的可变映射。您的getter也存在根本性的缺陷,因为每次访问它时它都会返回一个全新的可变映射,所以一旦您修改它并稍后返回从中检索值,这些值就会消失。此语法转换为sl.getValues().set(“user”,“other”)
。不,你不能让它调用setValues()
。很好的解释@Tenfour04,让我回顾一下我的代码:)我现在看到了你的问题,Tenfour04和AlexeyRomanov都说了。所以不可能用这种语法sl.values[“user”]=“other”
来触发setter??不,我认为你对能手和二传手的工作有一个基本的误解。setter更改mapsl
的值。如果不向setter传递新值,则无法触发setter。在这种情况下,新值将是一个全新的可变映射。您的getter也存在根本性的缺陷,因为每次访问它时它都返回一个全新的MutableMap,所以一旦您修改它并稍后返回从中检索值,这些值就会消失