【问题标题】:Algebraic data types in KotlinKotlin 中的代数数据类型
【发布时间】:2016-08-13 17:01:01
【问题描述】:

我正在尝试弄清楚如何在 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>()
}

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

val myTree1: Tree<Int> = Node(Leaf(4), Leaf(2))

但是我也想有一个“空”类型,所以我可以表达以下内容:

val myTree1: Tree<Int> = Node(Node(Leaf(4), Leaf(3)), Empty)

我尝试了以下方法:

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

虽然我得到了在 object Empty: Tree() 中需要 Type 参数的错误,这实际上是很合乎逻辑的。

我试过了

object Empty: Tree<T>()

但它导致“未解决的引用:T”。作为最后的手段,我尝试写作

object Empty<T>: Tree<T>()

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

有没有办法在 Kotlin 中表达这一点? Empty 应该是一个单例,这就是为什么它应该是一个对象。通过使其成为一个类,它解决了编译器问题,但是我必须像 => Empty() 那样在它后面加上括号。此外,它创建了不必要的对象,而它实际上应该是一个单例值。

如果能在这个问题上提供任何帮助,我将不胜感激。 :)

【问题讨论】:

    标签: kotlin algebraic-data-types


    【解决方案1】:

    首先您需要将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>()
    }
    

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

    【讨论】:

    • 它有效,谢谢!另外,我也学到了关于Nothing的东西。 :)
    • 这里不需要out - 没有它也可以。请澄清
    • @voddan 如果您删除 out,将无法创建带有 LeafEmptyNode
    • 如果我需要 T 具有可比性(我正在考虑 BST)怎么办?声明 sealed class Tree&lt;out T : Comparable&lt;T&gt;&gt; {..} 给出错误“Kotlin:类型参数 T 被声明为 'out' 但出现在 Comparable 类型中的 'in' 位置”
    • @David Soroko:您是否为 Comparable 示例找到任何可行的解决方案?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 2018-05-30
    • 2017-11-09
    • 1970-01-01
    相关资源
    最近更新 更多