Say I want to declare a simple algebraic datatype for integer lists:

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

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

Data class must have at least one primary constructor parameter

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

    sealed class Nil() : IntList()
    

    then I lose the free implementations of hashCode() and equals() that come for free with data class declarations.

EDIT

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

object Nil : IntList()

However, what would we do if our lists were parameterized by a type parameter? That is, now the first two lines of our definition would be

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

我们不能为任何A声明从List<A>派生的多态单例Nil对象,因为我们必须在声明时为A提供具体类型.解决方案(取自this post)是将A声明为协变类型参数,并将Nil声明为List<Nothing>的子类型,如下所示:

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))

推荐答案

Because data class without data doesn't make sense. Use object for singletons:

object Nil : IntList()

Kotlin相关问答推荐

在KMM合成多平台中创建特定于平台的视图

Mockk:对同一函数进行两次存根会忽略第一个行为

如何注入返回通用列表的转换器?

在 map 中查找键与在 kotlin 中查找 firstOrNull

有没有什么方法或算法可以在没有存储的情况下生成唯一的随机数?

如果不在可组合函数中,如何获取 stringResource

每个 Kotlin 版本的默认 Kotlin 语言版本是什么?

为什么 Kotlin 中的 Double 和 Long 类型不推荐直接转换为 Char?

验证构造函数中的值组合

多次运行espresso测试

有没有办法重用 Job 实例?

Kotlin 协程中的 Dispatchers.Main 和 Dispatchers.Default 有什么区别?

Kotlin 静态函数:伴生对象,@JvmStatic @JvmField

将 jetpack compose 添加到现有元素

如何通过反射使用 Kotlin 对象

将协同路由调用放在存储库或ViewModel中哪个更好?

Android:在 DAO 中使用 Room 数据库和 LiveData 架构

Kotlin解构when/if语句

如何从kotlin中的类实例化对象

Kotlin - 具有私有构造函数的类的工厂函数