2016-04-20 21 views
12

Ich versuche herauszufinden, wie man in Kotlin algebraische Datentypen verwendet, also versuche ich, einen einfachen BinaryTree-Typ wie folgt zu implementieren.Algebraische Datentypen in Kotlin

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

Das ist alles in Ordnung, und läßt mich den folgenden Baum konstruieren:

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

Jedoch habe ich auch eine „leere“ Art haben möchte, so kann ich folgende ausdrücken:

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

ich habe versucht, die folgenden:

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

Ich bekomme zwar den Fehler, dass Type-Argument am Objekt Empty: Tree() erwartet wird, was eigentlich ziemlich logisch ist.

versuchte ich

object Empty: Tree<T>() 

Aber es führte zu "Ungelöste Referenz: T". Als letzten Ausweg, versucht zu schreiben I

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

Aber die Compiler sagt „Typ Parameter nicht für Objekte erlaubt sind“

Gibt es eine Möglichkeit, dies in Kotlin auszudrücken? Leer sollte ein Singleton sein, deshalb sollte es ein Objekt sein. Indem es zu einer Klasse gemacht wird, löst es die Probleme des Compilers, aber dann muss ich die Klammern danach setzen => Empty(). Außerdem erzeugt es unnötige Objekte, während es eigentlich ein Singleton-Wert sein sollte.

Ich würde jede Hilfe zu diesem Thema schätzen. :)

Antwort

14

Zuerst müssen Sie T einen out Parameter vornehmen. Dann können Sie Nothing als ein Typargument für Empty verwenden.

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 ist eine besondere Art in Kotlin, die keine Instanz haben kann und ist ein Subtyp von allen anderen Typen. Also würde ich sagen, es ist das Gegenteil zu Any in Kotlin-Typ-Hierarchie.

+2

Es funktioniert, danke! Auch ich habe etwas über nichts gelernt. :) – pjozsef

+0

brauchst du nicht "out" hier - es funktioniert ohne es. Bitte klären Sie das – voddan

+2

@voddan, wenn Sie 'out' entfernen, wird es unmöglich, einen' Node' mit einem 'Leaf' und dem' Empty' zu erstellen. – Michael