当前位置: 首页 > 知识库问答 >
问题:

在Kotlin中,如何声明构造函数参数为零的数据类?

东方富
2023-03-14

假设我想为整数列表声明一个简单的代数数据类型:

sealed class IntList
data class Cons(val head: Int, val tail: IntList): IntList()
data class Nil() : IntList()

但是,最后一个声明导致一个错误

数据类必须至少有一个主构造函数参数

>

  • 为什么存在这种限制?查看文档,似乎没有很好的技术理由要求数据类构造函数为非空
  • 不需要编写大量样板代码就可以表达空构造函数吗?如果我把最后的声明改成

    sealed class Nil() : IntList()
    

    然后我就失去了hashCode()equals()的免费实现,它们是通过数据类声明免费提供的。

    编辑

    亚历克斯·费拉托夫在下面给出了一个简短的解决方案。显然,您永远不需要超过一个Nil实例,所以我们可以定义一个单例对象

    object Nil : IntList()
    

    然而,如果我们的列表是由类型参数参数化的,我们会怎么做呢?也就是说,现在我们定义的前两行是

    sealed class List<A>
    data class Cons<A>(val head: A, val tail: List<A>): List<A>()
    

    我们不能声明从List派生的多态单例Nil对象

    sealed class List<out A>
    data class Cons<A>(val head: A, val tail: List<A>): List<A>()
    object Nil : List<Nothing>()
    

    这让我们可以写作

    val xs: List<Int> = Cons(1, Cons(2, Nil))
    val ys: List<Char> = Cons('a', Cons('b', Nil))
    

  • 共有3个答案

    陈松
    2023-03-14

    如果你真的想要源代码的一致性,你可以使用默认值来尽可能地减少数据类型。

    data class Nil(val _u: Byte = 0) : IntList()
    

    或者

    data class Nil(val _u: Nothing? = null) : IntList()
    
    宗晟
    2023-03-14

    你必须创建一个普通的类

    class Nil : IntList()
    

    然后自己实现hashCode()equals()

    没有字段的数据类没有任何意义,因为它的工作是表示数据。

    或者:可以使用一个对象类(正如Alex Filatov所说),它是一个单实例类。由于不需要为每个Nil实例指定状态,因此它们可以共享一个状态。

    端木令雪
    2023-03-14

    因为没有数据的数据类没有意义。对单身者使用对象

    object Nil : IntList()
    
     类似资料:
    • 我正在尝试使用recyclerview和room库创建一个简单的ToDoList应用程序。在使用room和mvvm架构方面,我正在遵循android开发者代码实验室,我似乎遇到了困难。我已经设置了应用程序的每一层,但在尝试使用ViewModelProvider实例化ViewModel时出现了一个错误。下面是我的ViewModel类中的代码。 } 下面是我试图初始化ViewModel的main片段中

    • 我是新手。我想在Person类驱动的Employee类中添加age参数。我怎么能在科特林做到?! 我的错误是这样的: 为什么不能在员工构造函数中使用var或val?!我犯了什么错误?

    • 我是新的Android和Java,并试图使基于位置的应用程序。 编辑 我做了一个非常非常简单的测试代码,得到了同样的错误。这是java: 我也犯了同样的错误。以下是我的应用程序级构建中的依赖项。格雷德尔: 原帖 我试图使用ViewModel和LiveData来更新用户位置,因为我知道这是生命周期感知的最佳方式。我有一个默认的地图活动... 一个扩展LiveData以存储用户位置的类。。。 以及一个

    • 我有以下代码: 我不希望字段ui有一个getter,但是kotlin在默认情况下会生成它,因为它是构造函数中定义的val。 在properties and fields文档中,我发现我可以用以下代码生成一个私有getter 但我在构造函数定义中找不到这样做的方法