2017-10-14 7 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メソッドは_namesフィールドは、実際のデータを保持し、彼らはMutableList<String>にキャストし、それに追加しようとした場合、彼らはUnsupportedOperationExceptionを取得することを意味し、外部からのアクセスがありますプロパティ名を介して行われる

+1

おかげjrtapsell、 はい、私は私もこの第二の可変性を維持することができます知っている...しかし、追加の乱雑さを必要に応じて、それは確認されませんでした。.. 私はそれがまた、このようにうまくいくと思う: 'valの名前:List = _names' – JWT

+0

...それはおそらくキャストを防ぎませんが、 – JWT

+0

名前プロパティは、名前の不変なビューとして機能しますが、クラッタを減らすことができればいいです。 – jrtapsell

0

変更可能なリストをアンダースコア(Kotlinでは一種の「フィールド」)を持つプライベートプロパティとして定義し、別のパブリックの読み取り専用プロパティで公開します。

「フィールドは、」読み取り専用の場合、これは(@JWTによって提案された)トリック を行います:「フィールドが」再割り当てされる可能性がある場合

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

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

、それはようゲッターを定義する必要があります機能(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ご利用いただけます。

関連する問題