Kotlin酒店的私人吸气剂和公共二传手

问题描述 投票:36回答:3

如何在Kotlin建造一个拥有私人吸气剂(或者只是没有它)但拥有公共二传手的物业?

var status
private get

不适用于错误:Getter visibility must be the same as property visibility

在我的例子中,原因是Java互操作:我希望我的Java代码能够调用setStatus但不能调用getStatus

java kotlin kotlin-interop
3个回答
29
投票

目前在Kotlin,不可能拥有一个具有比该财产更明显的二传手的财产。问题跟踪器中存在语言设计问题,请随时观看/投票或分享您的用例:https://youtrack.jetbrains.com/issue/KT-3110


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"
}

1
投票

自Kotlin 1.0以来,可以使用基于@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

编译错误也非常有用:

使用'getter for property:Int'是一个错误。财产只能写。


用例

  1. 主要用例显然是允许编写属性但不读取的API: user.password = "secret" val pw = user.password // forbidden
  2. 另一种情况是修改内部状态的属性,但不将其自身存储为字段。 (可以使用不同的设计更优雅地完成)。 body.thrust_force = velocity body.gravity_force = Vector(0, 0, 9.8) // only total force accessible, component vectors are lost val f = body.forces
  3. 此模式对于以下类型的DSL也很有用: server { port = 80 host = "www.example.com" } 在这种情况下,值只是用作一次性设置,此处描述的只写机制可以防止意外读取属性(可能尚未初始化)。

限制

由于此功能不是针对此用例设计的,因此它具有某些限制:

  • 如果使用属性引用访问,则编译时错误将变为运行时错误: val ref = wo::property val x = ref.get() // throws NotImplementedError
  • 反思也是如此。
  • 此功能不能外包到委托中,因为错误弃用的getValue()方法不能与by一起使用。
© www.soinside.com 2019 - 2024. All rights reserved.