【问题标题】:Cannot return a String in Kotlin when don't "private"不“私有”时无法在 Kotlin 中返回字符串
【发布时间】:2018-08-09 22:13:02
【问题描述】:

为什么当我将用户名设为公开时会出错:

错误:(2, 5) Kotlin:平台声明冲突:以下 声明具有相同的 JVM 签名 (getUserName()Ljava/lang/String;): fun(): 用户定义的字符串 fun getUserName(): 用户中定义的字符串

错误:(4, 5) Kotlin:平台声明冲突:以下声明具有相同的 JVM 签名(getUserName()Ljava/lang/String;): fun(): 用户定义的字符串 fun getUserName(): 用户定义的字符串

但我将 userName 设为私有可以正常工作

 class User{
            /*private*/ var userName: String = "Emily"

            fun getUserName(): String{
                return userName
            }
        }

        fun main(args: Array<String>){
            val User = User()
            print(User.getUserName())
        }

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    通过将userName 属性设为public,Kotlin 将为您创建相应的getUserName()setUserName() 函数。当它这样做时,编写自己的 getUserName() 是多余的 - 具有相同签名的相同函数实际上存在两次 - 编译器不允许这样做。

    如果您希望userName 字段成为公共属性(带有生成的getter 和setter),那么您也不能自己编写getter。这样就足够了:

    var userName: String = "Emily"
    

    如果您希望 userName 拥有一个 public 获取器和一个 private 设置器(这似乎是您的意图),这就是 Kotlin 的实现方式:

    var userName: String = "Emily"
        private set
    

    最后,您仍然可以在属性上创建自定义访问器(例如,如果您想要额外的逻辑,例如以小写形式返回它)。 Kotlin 的实现方式如下所示:

    private var _userName: String = "Emily"
    var userName: String
        get() = _userName.toLowerCase()
        set(value) { _userName = value }
    

    另外,请注意,您访问该属性的方式会有所不同,具体取决于您是从 Kotlin 还是 Java 访问它。在 Kotlin 中,您只需编写 user.userName,但在 Java 中,您将编写 user.getUserName()

    【讨论】:

    • 哦。非常感谢
    【解决方案2】:

    当您定义var userName 时,您就是really defining a property,而不仅仅是一个字段。伴随该属性而来的是隐式的getUserName()setUserName() 方法。通过添加您自己的 getUserName(),您将影响 Kotlin 自动为您创建的那个。

    您可以放心地删除您的 getUserName() 并将您的字段设为非私有,它应该可以正常工作。编写代码的惯用方式是这样的:

    class User {
        var userName: String = "Emily"
    }
    
    fun main(args: Array<String>){
        val user = User()    // Note changed val from User to user.
        print(user.userName) // Note, this really calls the getter
    }
    

    【讨论】:

    • 非常感谢
    【解决方案3】:

    在 Kotlin 中,正在为每个属性创建一个 setter 和 getter(除非可见性禁止它),例如对于您的userName,它的名称恰好与您另外提供的名称完全相同:getUserName()。结果是名称冲突。请注意,对于var,还会生成设置器。将val 用于只读属性。

    实际上,您不需要像这样显式的 getter。只需这样做:

    class User{
        /*private*/ var userName: String = "Emily"
    }
    
    //use property syntax
    val user = User()
    print(user.userName)
    

    【讨论】:

    • 我明白了。非常感谢
    【解决方案4】:

    我只想添加更多关于private 字段的信息。当你用private 修饰符声明一个字段时,Kotlin 不会生成 getter/setter

    class User {
    
        private var userName = "Na"
    
        fun getUserName(): String {
            return userName;
        }
    
        fun setUserName(v: String) {
            userName = v
        }
    
    }
    

    当您声明上述方法(getter 和 setter)时,这些方法将被视为 用户定义 方法。

    【讨论】:

    • @halfer 下一篇文章我会牢记这一点,并会尝试编辑我以前的文章。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-01-31
    • 2019-05-11
    • 2021-10-22
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    • 2023-03-30
    相关资源
    最近更新 更多