Kotlinで、プライベートゲッターを持っている(または持っていない)が、パブリックセッターを持っているプロパティを作成する方法は?
var status
private get
エラーで動作しません:Getter visibility must be the same as property visibility
私の場合、理由はJava interop:私のJavaコードがsetStatus
を呼び出せるが、getStatus
。
Kotlinでは、現時点ではプロパティよりも目立つセッターを持つプロパティを持つことは不可能です。これに関する問題トラッカーには言語設計の問題がありますので、自由に見たり投票したり、ユースケースを共有してください: https://youtrack.jetbrains.com/issue/KT-311
現在のKotlinバージョン(1.0.3)では、唯一のオプションは、次のような個別のsetterメソッドを持つことです:
class Test {
private var name: String = "name"
fun setName(name: String) {
this.name = name
}
}
外部ライブラリがゲッターにアクセスすることを制限したい場合、 internal
可視性修飾子を使用して、ライブラリ内でプロパティ構文を引き続き使用できます。
class Test {
internal var name: String = "name"
fun setName(name: String) { this.name = name }
}
fun usage(){
val t = Test()
t.name = "New"
}
コンパイル時エラーを伴う書き込み専用プロパティcanは、Kotlin 1.0以降、_@Deprecated
_に基づく回避策を使用して実現されます。
Kotlinでは、非推奨の関数をレベルERROR
でマークできます。これにより、呼び出し時にコンパイル時エラーが発生します。プロパティのget
アクセサーにerror-deprecatedとして注釈を付け、バッキングフィールドと組み合わせて(プライベート読み取りが可能になるように)、目的の動作を実現します。
_class WriteOnly {
private var backing: Int = 0
var property: Int
@Deprecated("Property can only be written.", level = DeprecationLevel.ERROR)
get() = throw NotImplementedError()
set(value) { backing = value }
val exposed get() = backing // public API
}
_
使用法:
_val wo = WriteOnly()
wo.property = 20 // write: OK
val i: Int = wo.property // read: compile error
val j: Int = wo.exposed // read value through other property
_
コンパイルエラーも非常に役立ちます。
「プロパティのゲッター:Int」を使用するとエラーになります。プロパティは書き込みのみ可能です。
主な使用例は、明らかにプロパティの書き込みは許可するが読み取りは許可しないAPIです。
_user.password = "secret"
val pw = user.password // forbidden
_
別のシナリオは、内部状態を変更するプロパティですが、それ自体はフィールドとして保存されません。 (異なるデザインを使用してよりエレガントに行うことができます)。
_body.thrust_force = velocity
body.gravity_force = Vector(0, 0, 9.8)
// only total force accessible, component vectors are lost
val f = body.forces
_
このパターンは、次の種類のDSLにも役立ちます。
_server {
port = 80
Host = "www.example.com"
}
_
このような場合、値は単に1回限りの設定として使用され、ここで説明する書き込み専用メカニズムは、プロパティ(まだ初期化されていない可能性がある)を誤って読み取ることを防ぐことができます。
この機能はこのユースケース向けに設計されていないため、特定の制限があります。
プロパティ参照を使用してアクセスすると、コンパイル時エラーはランタイムエラーに変わります。
_val ref = wo::property
val x = ref.get() // throws NotImplementedError
_
反射についても同じことが言えます。
error-deprecatedgetValue()
メソッドはby
と共に使用できないため、この機能をデリゲートにアウトソースすることはできません。 。