【问题标题】:Unable to print the values of an instance of my model无法打印我的模型实例的值
【发布时间】:2018-08-13 12:34:41
【问题描述】:

我知道这是一个非常基本的问题,但回答这个问题将解决我的许多疑问。

val new_parent = ParentDetails(intent.extras.getString("name"), 
    intent.extras.getString("email"),
    intent.extras.getString("parent_relation"),
    intent.extras.getString("locationdata"))

println(new_parent.tostring())

上面的代码不会打印类中存在的各种字段及其值。

ParentDetails 是我创建的模型,其中包含一些已初始化的字段。 ParentDetails 模型:

class ParentDetails {
    var parent_id: Int = 0
    var parent_name: String = ""
    var parent_email: String = ""
    var parent_relation: String = ""
    var parent_location: String=""

    constructor(parent_name: String, parent_email: String, parent_relation: String,parent_location:String) {
        this.parent_name = parent_name
        this.parent_email = parent_email
        this.parent_relation = parent_relation
        this.parent_location = parent_location
    }

    public fun getparentId(): Int {
        return parent_id
    }

    fun ParentDetailsprintme() {
        println(parent_name)
        println(parent_email)
        println(parent_relation)
        println(parent_location)
     }
}

事实上,它打印 null 并访问单个字段,它打印空字符串(它的初始化方式)。

我们如何解释这个?

【问题讨论】:

    标签: class object constructor kotlin


    【解决方案1】:

    据我了解,您的问题是调用 println(new_parent.tostring()) 不会打印您想要在函数 ParentDetailsprintme 中打印的内容。

    首先,你有一个错字,正确的电话应该是new_parent.toString()

    请注意,它可以简化为println(new_parent)

    它不会打印您在ParentDetailsprintme 方法中定义的内容,因为该方法未被调用。

    println(new_parent.toString()) 打印的实际上是对象的哈希码,因为这是每个对象的默认行为。

    要使其正常工作,请像 println(new_parent.ParentDetailsprintme()) 一样调用它或覆盖 toString() 方法,例如:

    override fun toString() = "$parent_name $parent_email $parent_relation $parent_location"
    

    然后是下面

    val new_parent = ParentDetails("myName", "myEmail", "myParent_relation", "myLocationdata")
    println(new_parent)
    

    应该打印

    myName myEmail myParent_relation myLocationdata
    

    Kotlin 的 println 函数只是在底层调用 System.out.println(message),这将调用 String.valueOf()(例如,String.valueOf(Object object) 用于对象,它将调用传递对象的 toString() 方法)。

    /** Prints the given message and newline to the standard output stream. */
    @kotlin.internal.InlineOnly
    public inline fun println(message: CharArray) {
        System.out.println(message)
    }
    

    更新(“使用数据类方法也可以”):

    如果您将类设为数据类:

    data class ParentDetails(
            val parent_id: Int = 0,
            val parent_name: String = "",
            val parent_email: String = "",
            val parent_relation: String = "",
            val parent_location: String = ""
    )
    

    然后你执行

    val new_parent = ParentDetails(0, "myName", "myEmail", "myParent_relation", "myLocationdata")
    println(new_parent)
    

    您将收到结果

    ParentDetails(parent_id=0, parent_name=myName, parent_email=myEmail, parent_relation=myParent_relation, parent_location=myLocationdata)
    

    这是因为data classes 覆盖了toString() 函数:

    编译器会自动从所有 在主构造函数中声明的属性:

    • equals()/hashCode() 对;
    • toString() 形式为“User(name=John, age=42)”;

    【讨论】:

    • 为什么我写的方法不起作用?使用数据类方法也可以。但我正在寻找一个解释,说明为什么我写的方式没有按照我认为的方式工作。
    【解决方案2】:

    您是否检查过您从intent.extras 收到的数据是否有效?

    另外我建议您使用data class 作为您的模型。 它看起来像这样:

    data class ParentDetails(
        var parent_id: Int = 0,
        var parent_name: String = "",
        var parent_email: String = "",
        var parent_relation: String = "",
        var parent_location: String = ""
    )
    

    您将能够像这样使用它:

    val new_parent = ParentDetails(
            parent_name = intent.extras.getString("name"),
            parent_email = intent.extras.getString("email"),
            parent_relation = intent.extras.getString("parent_relation"),
            parent_location = intent.extras.getString("locationdata")
        )
        println(new_parent.tostring())
    

    【讨论】:

    • 谢谢。这行得通,但为什么我写的方式不起作用?此外,intent.extras 返回有效。我已经检查过了。
    • @Eswar 数据类为您(以及其他一些人)生成toString() 乐趣。我想这是你的主要问题。查看data class 了解更多信息。
    【解决方案3】:

    如前所述,您有一个错字。 toString 返回对象的哈希码,除非它被覆盖以返回其他内容。查找原始实现以获取更多详细信息。

    通过覆盖toString 方法,您可以更改它返回的内容,并通过它更改print(someClass) 时打印的内容。 DVarga 在他们的回答中表明了这一点。

    Data classes 自动生成包含类内容的toString 方法。因此,创建数据类是获取包含数据的输出的捷径。

    您的方法不起作用的原因是您没有调用它。如果你调用它而不是toString,你会得到打印的数据。

    另外,toString 在打印类时会被显式调用。不用打print(someInstance.toString())print(someInstance)就够了。


    当我写答案时,您不需要在 Kotlin 中使用辅助构造函数。无论是否是数据类,主构造函数都会显着缩短您的代码。此外,您应该研究命名约定。

    【讨论】:

      猜你喜欢
      • 2012-07-15
      • 1970-01-01
      • 1970-01-01
      • 2022-12-22
      • 2019-07-07
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多