Kotlin中的代数数据类型

pjo*_*sef 14 algebraic-data-types kotlin

我试图弄清楚如何在Kotlin中使用代数数据类型,所以我试图通过以下方式实现基本的BinaryTree类型.

sealed class Tree<T>{
  class Node<T>(val left: Tree<T>, val right: Tree<T>): Tree<T>()
  class Leaf<T>(val value: T): Tree<T>()
}
Run Code Online (Sandbox Code Playgroud)

这很好,让我构建以下树:

val myTree1: Tree<Int> = Node(Leaf(4), Leaf(2))
Run Code Online (Sandbox Code Playgroud)

但是我想要一个"空"类型,所以我可以表达以下内容:

val myTree1: Tree<Int> = Node(Node(Leaf(4), Leaf(3)), Empty)
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法:

sealed class Tree<T>{
  class Node<T>(val left: Tree<T>, val right: Tree<T>): Tree<T>()
  class Leaf<T>(val value: T): Tree<T>()
  object Empty: Tree()
}
Run Code Online (Sandbox Code Playgroud)

虽然我得到的错误是在对象Empty:Tree()中期望Type参数,这实际上是非常合乎逻辑的.

我试过了

object Empty: Tree<T>()
Run Code Online (Sandbox Code Playgroud)

但它导致了"未解决的参考:T".作为最后的手段,我尝试写作

object Empty<T>: Tree<T>()
Run Code Online (Sandbox Code Playgroud)

但编译器说"不允许对象使用类型参数"

有没有办法在Kotlin表达这个?空应该是单身,这就是为什么它应该是一个对象.通过使它成为一个类,它解决了编译器的问题,但是我必须在它之后添加括号=> Empty().此外,它创建了不必要的对象,而它确实应该是一个单例值.

我对这个问题有任何帮助表示感谢.:)

Mic*_*ael 20

首先,您需要创建T一个out参数.然后你可以Nothing用作类型参数Empty.

sealed class Tree<out T>{
  class Node<T>(val left: Tree<T>, val right: Tree<T>): Tree<T>()
  class Leaf<T>(val value: T): Tree<T>()
  object Empty: Tree<Nothing>()
}
Run Code Online (Sandbox Code Playgroud)

Nothing是Kotlin中的一种特殊类型,它不能有实例,是所有其他类型的子类型.所以我会说它与AnyKotlin类型层次结构相反.

  • 它有效,谢谢!另外,我也学到了一些关于什么的东西.:) (3认同)
  • @voddan如果删除`out`,将无法使用`Leaf`和`Empty`创建`Node`. (3认同)
  • 如果我需要T可比较(我在考虑BST)怎么办?声明`密封类树<out T:Comparable <T >> {..}`给出错误"Kotlin:类型参数T被声明为'out',但出现在Comparable <T>类型的'in'位置" (2认同)