Перегрузка оператора индексированного доступа для члена MutableList в Kotlin - PullRequest
0 голосов
/ 09 апреля 2020

Это мой сценарий, у меня есть несколько MutableList членов, первый для хранения String (называемый sl ), а остальные для Any (называемые объекты , names , ...), и мне нужно получить доступ к значениям в объектах , names , а остальные 2 способами:

  1. sl через индекс,
  2. объекты , имена и остальное через строковое значение, сохраненное в sl ,

Может быть, пример более понятен:

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

myStringList.objects["keyname"] = "keyvalue"  // write and read for the rest
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]
    }
}

Не уверен, что другая реализация более подходящим для моего сценария, любое предложение приветствуется.

1 Ответ

1 голос
/ 09 апреля 2020

TL; DR

Если вы хотите получить к ним доступ извне, эти 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. Функции расширений, объявленные внутри , к классу можно обращаться только в этом классе или в одном из его подклассов, поэтому вы все равно можете использовать свою версию (например, myStringList.objects["keyname"]), только если вы вызываете эта операторная функция внутри StringList.

  2. Я думаю, вы должны обработать случай, в котором indexOf() возвращает -1, в противном случае функции set и get вызовет исключение за пределами допустимого.

  3. Если вы можете, рассмотрите возможность использования простого Map<String, Any> для вашего варианта использования.

...