[英]Private getter and public setter for a Kotlin property
如何在 Kotlin 中創建具有私有 getter(或只是沒有)但具有公共 setter 的屬性?
var status
private get
不會出現錯誤: Getter visibility must be the same as property visibility
就我而言,原因是 Java 互操作:我希望我的 Java 代碼能夠調用setStatus
而不是getStatus
。
目前在 Kotlin 中不可能有一個屬性的 setter 比屬性更明顯。 問題跟蹤器中存在一個語言設計問題,請隨時觀看/投票或分享您的用例: https : //youtrack.jetbrains.com/issue/KT-3110
在當前的 Kotlin 版本 (1.0.3) 中,唯一的選擇是使用單獨的setter方法,如下所示:
class Test {
private var name: String = "name"
fun setName(name: String) {
this.name = name
}
}
如果您希望限制外部庫訪問 getter,您可以使用internal
可見性修飾符,允許您仍然在庫中使用屬性語法:
class Test {
internal var name: String = "name"
fun setName(name: String) { this.name = name }
}
fun usage(){
val t = Test()
t.name = "New"
}
編譯時錯誤只寫屬性可以自科特林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
編譯錯誤也很有幫助:
使用 'getter for 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" }
在這種情況下,值僅用作一次性設置,此處描述的只寫機制可以防止意外讀取屬性(可能尚未初始化)。
由於此功能不是為此用例設計的,因此具有某些限制:
如果使用屬性引用訪問,編譯時錯誤會變成運行時錯誤:
val ref = wo::property val x = ref.get() // throws NotImplementedError
反射也是如此。
此功能不能外包給委托,因為錯誤棄用的getValue()
方法不能與by
一起使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.