2017-09-11 28 views
7

私は、整数リストの簡単な代数的データ型を宣言したいと言う:Kotlinでは、コンストラクタパラメータがゼロのデータクラスをどのように宣言しますか?

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

しかし、エラーの最後の宣言の結果が

データクラスは、少なくとも1つの第一級のコンストラクタパラメータ

を持っている必要があります
  1. なぜこの制限がありますか?ドキュメントを見ると、データクラスのコンストラクタにnullでないものを要求するための優れた技術的な理由はないようです。
  2. 定型のコードをたくさん書かなくても、無意味なコンストラクタを表現することはできますか?私は

    sealed class Nil() : IntList() 
    

    のようなものに最後の宣言を変更した場合、私はdata class宣言と無料で来hashCode()equals()の自由な実装を失います。

EDIT

アレックスフィラトフは以下の素敵な短い溶液を得ました。もちろん、あなたはNilの複数のインスタンスを必要としませんので、私たちのリストは型パラメータによってパラメータ化された場合、私たちはシングルトンオブジェクトに

object Nil : IntList() 

を定義することができますしかし、私たちは何をしますか?それは我々が時Aための具体的な種類を提供する必要があるため、今私たちの定義の最初の2行は、

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

は、私たちはどんなAためList<A>から派生した多型シングルトンNilオブジェクトを宣言することはできませんでしょう、です宣言。 (this postから取られた)ソリューションは、共変の型パラメータとしてAを宣言し、次のようにList<Nothing>のサブタイプとしてNilを宣言することです:

sealed class List<out A> 
data class Cons<A>(val head: A, val tail: List<A>): List<A>() 
object Nil : List<Nothing>() 

これはdata classので、私たちはデータなし

val xs: List<Int> = Cons(1, Cons(2, Nil)) 
val ys: List<Char> = Cons('a', Cons('b', Nil)) 
+0

関連:https://stackoverflow.com/questions/37873995/how-to-create-empty-constructor-for-data-class-in-kotlin-androidしかし、あなたの状況に合っていないようです。 – BakaWaii

+1

また、 "一次コンストラクタで宣言されていないプロパティは、等価チェックとハッシュコード計算に参加しません。" – BakaWaii

+0

@UlrikRasmussenなぜhashCode()とequals()が必要なのですか?クラスにはフィールドが含まれていないはずですか? –

答えて

10

を書くことができます意味がありません。シングルトンのためのobjectを使用します。

object Nil : IntList() 
+0

これは、タイプパラメータを持たない単純な代数的データ型であった私のユースケースでうまくいきました。しかし、パラメータ化された型に対してnullaryコンストラクタをどのように表現すればよいでしょうか?たとえば、コンスコンストラクタ 'データクラスCons (val h:A、val t:List ):リスト()'で 'sealed class List 'に一般化しましょう。多態性オブジェクト 'object Nilを宣言することはできません:リスト()' –

+0

解決策が見つかりました。 –

0

あなたは

class Nil : IntList() 

通常のクラスを作成し、 hashCode()equals()を自分で実装する必要があります。

フィールドを持たないデータクラスは、データの表現であるため意味がありません。


または:(Alex Filatovが言ったように)あなたは、単一のインスタンスクラスであるオブジェクトクラスを使用することができます。単一のNilインスタンスごとに状態が必要なわけではないので、1つのインスタンスを共有できます。

-2

ソースコードの一貫性が本当に必要な場合は、可能な限り小さなデータ型にデフォルト値を使用できます。

data class Nil(val _u: Byte = 0) : IntList() 

または

data class Nil(val _u: Nothing? = null) : IntList() 
関連する問題