2017-10-14 48 views
3

我是Kotlin的新手,并且正在解决返回不可变内部可变列表版本的问题。Kotlin:暴露API中的不可变列表

我回顾了下面的'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) 

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

回答

4

以下工作:

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

    fun addName(name: String) { 
     _names.add(name) 
    } 
} 

的toList意味着,如果他们将它转换为一个MutableList<String>并尝试添加到它,他们会得到一个UnsupportedOperationException,该_names字段保存真实的数据和外部访问通过名称属性完成

+1

感谢jrtapsell, 是的,我知道我能保持这样的第二个变量,以及...但不知道,如果需要额外的混乱.. 我认为它是这样工作的: 'VAL名:列表 = _names' – JWT

+0

...虽然这可能不会阻止转换 – JWT

+0

names属性只是用作_names的不可变视图,但如果可以减少杂波将会很好 – jrtapsell

0

将可变列表定义为具有下划线(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