如何在Kotlin建造一个拥有私人吸气剂(或者只是没有它)但拥有公共二传手的物业?
var status
private get
无法处理错误:Getter visibility must be the same as property visibility
就我而言,原因是Java互操作:我希望我的Java代码能够调用setStatus
而不是getStatus
。
答案 0 :(得分:28)
目前在Kotlin,不可能拥有一个属性比房产更明显的二人物。问题跟踪器中存在语言设计问题,请随时观看/投票或分享您的使用案例:https://youtrack.jetbrains.com/issue/KT-3110
答案 1 :(得分:24)
在当前的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"
}
答案 2 :(得分:1)
@Deprecated
的变通办法具有编译时错误的仅写属性 。
Kotlin允许标记级别ERROR
弃用的函数,这在调用时导致编译时错误。将属性的get
访问器注释为不赞成使用错误,并结合一个后备字段(以便仍可以进行私有读取),可以达到所需的行为:
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"
}
在这种情况下,值仅用作一次性设置,并且此处描述的只写机制可以防止意外读取属性(可能尚未初始化)。
由于此功能不是为此用例设计的,因此具有某些限制:
如果使用属性引用进行访问,则编译时错误将变为运行时错误:
val ref = wo::property
val x = ref.get() // throws NotImplementedError
对于反射也是如此。
此功能不能外包给委托,因为已弃用 getValue()
方法不能与by
一起使用。