假设我想为整数列表声明一个简单的代数数据类型:
sealed class IntList
data class Cons(val head: Int, val tail: IntList): IntList()
data class Nil() : IntList()
Run Code Online (Sandbox Code Playgroud)
但是,最后一个声明会导致错误
数据类必须至少有一个主构造函数参数
是否有可能表达无需构造函数而无需编写大量的样板代码?如果我将最后一个声明更改为类似的
sealed class Nil() : IntList()
Run Code Online (Sandbox Code Playgroud)
然后我失去了免费的实现hashCode()和equals()免费data class声明.
编辑
Alex Filatov给出了一个很好的简短解决方案.显然,您永远不需要多个实例Nil,因此我们可以只定义一个单例对象
object Nil : IntList()
Run Code Online (Sandbox Code Playgroud)
但是,如果我们的列表由类型参数参数化,我们会怎么做?也就是说,现在我们定义的前两行是
sealed class List<A>
data class Cons<A>(val head: A, val tail: List<A>): List<A>()
Run Code Online (Sandbox Code Playgroud)
我们不能声明Nil从List<A>any 派生的多态单例对象A,因为我们必须A在声明时提供具体类型.解决方案(取自这篇文章)是声明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>()
Run Code Online (Sandbox Code Playgroud)
这允许我们写
val xs: List<Int> = Cons(1, Cons(2, Nil))
val ys: List<Char> = Cons('a', Cons('b', Nil))
Run Code Online (Sandbox Code Playgroud)
小智 14
因为data class没有数据没有意义.使用object的单身:
object Nil : IntList()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1578 次 |
| 最近记录: |