【问题标题】:Kotlin: exposing immutable list in APIKotlin:在 API 中公开不可变列表
【发布时间】:2017-12-15 06:59:58
【问题描述】:

我是 Kotlin 的新手,正在努力解决返回内部可变列表的不可变版本的问题。

我查看了以下“Kotlin: Modifying (immutable) List through cast, is it legitimate?”并了解不可变列表实际上只是只读视图,不公开修改方法。

我想要一个公开“不可变”列表的类,并且仍然想利用 Kotlins 自动获取器(无需提供获取列表或列表成员的所有样板)

以下是一个坏主意(或者它会导致可能在未来版本中被阻止的问题)

class Foo {
  val names: List<String> = LinkedList;

  fun addName(name: String) {
    (names as LinkedList).add(name)
  }
}

我希望允许(例如):

  val foo = Foo;
  println(foo.names.size)

但仍然阻止调用者修改类的内部(至少尽可能)。例如删除元素或清除支持列表。

【问题讨论】:

    标签: collections kotlin


    【解决方案1】:

    以下作品:

    class Foo {
        private val _names: MutableList<String> = mutableListOf()
        val names: List<String>
            get() = _names.toList()
    
        fun addName(name: String) {
            _names.add(name)
        }
    }
    

    toList 意味着如果他们将其转换为MutableList&lt;String&gt; 并尝试添加到它,他们将获得UnsupportedOperationException_names 字段包含真实数据,外部访问通过 names 属性完成

    【讨论】:

    • 感谢 jrtapsell,是的,我知道我也可以维护第二个变量......但不确定是否需要额外的混乱......我认为它也可以这样工作:val name: List&lt;String&gt; = _names
    • ...虽然这可能不会阻止演员阵容
    • names 属性只是作为 _names 的不可变视图,但如果能减少混乱就更好了
    • 使用支持字段可以简化代码:link
    【解决方案2】:

    将可变列表定义为带下划线的私有属性(Kotlin 中的一种“字段”),并通过另一个公共只读属性公开它。

    如果“字段”是只读的,则可以解决问题 (@JWT 建议):

    class Foo {
        private val _names: MutableList<String> = mutableListOf()
        val names: List<String> = _names
    
        fun addName(name: String) {
            _names.add(name)
        }
    }
    

    如果“字段”可能被重新分配,则需要将 getter 定义为函数(注意 var _names):

    class Foo2 {
        private var _names: MutableList<String> = mutableListOf()
        val names: List<String>
            get() = _names
    
        fun addName(name: String) {
            _names.add(name)
        }
    
        fun reset() {
            _names = mutableListOf()
        }
    }
    

    测试可用here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      • 2019-07-14
      相关资源
      最近更新 更多