【问题标题】:Kotlin: private mutable property with only getterKotlin:只有 getter 的私有可变属性
【发布时间】:2018-08-29 11:47:05
【问题描述】:

我对 Kotlin 非常陌生,并试图将一个项目从 Java 迁移到它。我对 Kotlin 的属性和 getter/setter 以及可见性范围有点困惑。

我想要实现的是:

public class Foo {

    private int number;

    public int getNumber() {
        return number;
    }

    public void increment() {
        number++;
    }

}

所以基本上我需要创建一个具有私有属性number 的类。这个属性应该可以被公共 getter 访问,但它不应该有一个 setter。此外,该属性应该是内部可变的,以便可以使用increment() 等方法更改其值。

据我了解,我不能将它声明为val,因为在这种情况下,它是完全不可变的,即使在类的实例中也是如此,所以我不能递增它。看起来应该是var。但是我看不到使属性本身为private 和此属性的getter 为public 的选项,因为似乎属性及其getter/setter 应该具有相同的可见性范围...

【问题讨论】:

    标签: java kotlin


    【解决方案1】:

    如果您使用 Intellij,您只需将代码粘贴到 Kotlin 类中,就会收到以下信息:

    class Foo {
    
      var number: Int = 0
        private set
    
      fun increment() {
        number++
      }
    }
    

    而这基本上也是你问题的答案……

    private set 告诉 setter 仅私下可见。因此您可以在Foo 内访问它,但不能从外部访问。您明确设置的0(与Java 相比)。然后:默认情况下,属性和函数是public

    还要检查Kotlin reference regarding properties (specifically getter/setter)

    【讨论】:

    • 谢谢。我试图反之亦然:声明一个具有private 范围的字段和具有public 范围的getter(就像我们通常在Java 中所做的那样)并得到错误Getter visibility must be the same as property visibility。这让我很困惑。但是,是的,它的工作方式相反。
    • 好吧,您还可以执行以下操作:private var number: Int = 0fun getNumber() = number。然而,这不是标准的 Kotlin 方式 ;-) 这样你可以随意命名方法......你甚至可以返回其他东西然后属性......(但是!)在这里坚持标准肯定更好: -)
    • 是的,我有这个想法,但决定要求一种“Kotlin 方式”。再次感谢。
    • 很抱歉在 cmets 中提出讨论,但是否可以使用主构造函数声明相同的属性,以便我可以利用 data 关键字(使 Foo 成为数据类,但没有设置器)?
    • 不......你不能在构造函数中拥有private set。还要检查这个discuss.kotlinlang-post。在这种特殊情况下,您可能更愿意提供类似:data class(private var number : Int) { fun currentCount() = number }... 并且将来可能还会在构造函数中支持私有 setter/getter。
    【解决方案2】:

    我也是 kotlin 的新手,看来这是这样做的:

    class Foo {
        var number: Int = 0; private set
        fun increment() {
           ++number;
        }
    }
    

    作为specified in their documentation

    【讨论】:

      【解决方案3】:

      在 Kotlin 中,你的类会是这样的:

      class Foo {
          var number = 0
              get
              private set
      
          fun increment() {
              number++
          }
      }
      

      Getter 是公共的(但无论如何它是这样隐式创建的,所以实际上我们可以删除它)而 setter 是私有的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-18
        • 2021-11-11
        • 2018-08-06
        相关资源
        最近更新 更多