Kotlin中用于MutableList成员的索引访问操作符重载

huangapple go评论63阅读模式
英文:

Indexed access operator overload for a MutableList member in Kotlin

问题

以下是翻译好的内容:

这是我的情景,我有几个 MutableList 成员,第一个用于存储 String(称为 sl),其余用于存储 Any(称为 objectsnames 等),我需要通过两种方式访问 objectsnames 和其他成员中的值:

  1. 通过索引访问 sl
  2. 通过存储在 sl 中的字符串值访问 objectsnames 和其他成员,

也许一个示例会更清楚:

var tmpListItem = myStringList.sl[0]  // 只读访问 sl 列表

myStringList.objects["keyname"] = "keyvalue"  // 对其他成员进行读写操作
var tmpObj = myStringList.objects["keyname"]

myStringList.names["keyname"] = "keyvalue"
var tmpName = myStringList.names["keyname"]

我一直在尝试重载 MutableList 的索引访问运算符,但是我得到了这个错误:

类型不匹配:推断的类型为 String,但预期为 Int

到目前为止,这是我尝试的代码:

data class StringList(val str: String) {
    val sl = mutableListOf<String>()
    val objects = mutableListOf<Any?>()
    val names = mutableListOf<Any?>()
    val values = mutableListOf<Any?>()
    val strings = mutableListOf<Any?>()

    public operator fun <E> MutableList<E>.set(k: String, value: Any?) {
        val t = sl.indexOf(k)
        objects[t] = value
    }
    operator fun <E> MutableList<E>.get(e: String): Any? {
        val t = sl.indexOf(e)
        return objects[t]
    }
}

不确定是否有其他更适合我情景的实现方法,欢迎任何建议。

英文:

This is my scenario, I have several MutableList members, the first for storing String (called sl) and the rest for Any (called objects, names, ...), and I need to access the values in the objects, names and the rest through 2 ways:

  1. sl through the index,
  2. objects, names and the rest through the string value stored in sl,

Maybe an example is more clear:

var tmpListItem = myStringList.sl[0]  // read only for the sl list

myStringList.objects[&quot;keyname&quot;] = &quot;keyvalue&quot;  // write and read for the rest
var tmpObj = myStringList.objects[&quot;keyname&quot;]

myStringList.names[&quot;keyname&quot;] = &quot;keyvalue&quot;
var tmpName = myStringList.names[&quot;keyname&quot;]

I have been trying to overload the indexed access operator for a MutableList, but I get this error:

> Type mismatch: inferred type is String but Int was expected

This is my attempt so far:

data class StringList(val str: String) {
    val sl = mutableListOf&lt;String&gt;()
    val objects = mutableListOf&lt;Any?&gt;()
    val names = mutableListOf&lt;Any?&gt;()
    val values = mutableListOf&lt;Any?&gt;()
    val strings = mutableListOf&lt;Any?&gt;()

    public operator fun &lt;E&gt; MutableList&lt;E&gt;.set(k: String, value: Any?) {
        val t = sl.indexOf(k)
        objects[t] = value
    }
    operator fun &lt;E&gt; MutableList&lt;E&gt;.get(e: String): Any? {
        val t = sl.indexOf(e)
        return objects[t]
    }
}

Not sure if another implementation is more appropriate for my scenario, any suggestion is welcome.

答案1

得分: 1

如果您想从外部访问它们,那些 operator fun 不应该是 MutableList 的扩展。

data class StringList(val str: String) {
    val sl = mutableListOf<String>()
    val objects = mutableListOf<Any?>()

    operator fun set(k: String, value: Any?) {
        val t = sl.indexOf(k)
        objects[t] = value
    }
    operator fun get(e: String): Any? {
        val t = sl.indexOf(e)
        return objects[t]
    }
}

现在您可以这样使用它们:

myStringList["keyname"] = "keyvalue"
var tmp = myStringList["keyname"]

细节

这里有一些我想指出的事情:

  1. 在类内部声明的扩展函数只能在该类或其子类中访问,因此只有在 StringList 中调用该操作符函数时,您才能继续使用您的版本(例如 myStringList.objects["keyname"])。

  2. 我认为您应该处理 indexOf() 返回 -1 的情况,否则 setget 函数将抛出越界异常。

  3. 如果可能的话,考虑使用简单的 Map<String, Any> 来满足您的用例。

英文:

TL;DR

If you want to access them from outside, those operator fun shouldn't be extensions of MutableList.

data class StringList(val str: String) {
    val sl = mutableListOf&lt;String&gt;()
    val objects = mutableListOf&lt;Any?&gt;()

    operator fun set(k: String, value: Any?) {
        val t = sl.indexOf(k)
        objects[t] = value
    }
    operator fun get(e: String): Any? {
        val t = sl.indexOf(e)
        return objects[t]
    }
}

Now you can use them like so:

myStringList[&quot;keyname&quot;] = &quot;keyvalue&quot;
var tmp = myStringList[&quot;keyname&quot;]

Details

There are few things which I'd like to point out here:

  1. Extensions functions declared inside a class can be accessed only in that class or in one of its subclasses, so you can still use your version (e.g. myStringList.objects[&quot;keyname&quot;]) only if you are invoking that operator function inside StringList.

  2. I think you should handle the case in which indexOf() returns -1, otherwise the functions set and get will throw an out-of-bounds exception.

  3. If you can, consider to use a simple Map&lt;String, Any&gt; for your use case.

huangapple
  • 本文由 发表于 2020年4月9日 06:18:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/61110952.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定