2017-12-14 9 views
1

を検索:は、与えられたkotlinコードでkotlin空のデータクラスのプライマリコンストラクタの回避策

sealed class Event(val id:String= UUID.randomUUID().toString(), val timestamp:Instant = Instant.now()) 
data class BarEvent(val additionalInfo:String):Event() 
object FooEvent:Event() 
// data class CorrectFooEvent():Event() // invalid kotlin 

fun main(args: Array<String>) { 
    val b1 = BarEvent("b1") 
    val f1 = FooEvent 
    Thread.sleep(1000) 
    val b2 = BarEvent("b2") 
    val f2 = FooEvent 

    println("${b1.id} ${b1.timestamp} $b1") 
    println("${f1.id} ${f1.timestamp} $f1") 
    println("${b2.id} ${b2.timestamp} $b2") 
    println("${f2.id} ${f2.timestamp} $f2") 
} 

BarEventと全く問題はありません。

しかし、FooEventは、Eventのパラメータより多くのパラメータがありません。空のコンストラクタが必要です。それはデータクラスのために許可されていないので、私はそれをオブジェクトにしました。しかし、オブジェクトはシングルトンなので、インスタンス化されたイベントとして振る舞いません。

data classとしてクラスを維持する)私が見る唯一の回避策のようなものです:

sealed class Event(open val id:String= UUID.randomUUID().toString(), open val timestamp:Instant = Instant.now()) 
data class FooEvent(override val id:String= UUID.randomUUID().toString(), override val timestamp:Instant = Instant.now()):Event() 

しかし、それは非常にエレガントではありません。

答えて

2

必要な場合にだけtoString()hashCode()equals(Object)を通常のクラスにFooEventを変更し、追加(またはあなたのIDEを使用してそれらを生成):

class FooEvent: Event() { 
    override hashCode() = ... 
    override equals(other: Object) { 
     ... 
    } 
    override toString() = ... 
} 

をイベントにデータクラスを作成するには、単に未使用のプロパティを追加それに。かなり、それは現時点でKotlinにすることができように短いません:

data class FooEvent(val dummy: Unit = Unit) : Event() 

すぐにこの制限を削除する意図はないように思える:

+0

ありがとうございますが、それはまた、 "データクラス"のコピーアンドデストラクチャリング機能を失ったことを意味します。それで私は「クラスをデータクラスとして保持する」と言ったのです。 –

+0

彼らの決定は1.0時に意味があるようです。破壊されず、データクラスの継承もありません。しかし、今、ちょっと変だ...とにかくありがとう。 –

+0

編集前のあなたの答えは正しいです。この場合、データクラスは使用しないでください。データクラスのドキュメントから、継承されたフィールドはデータクラスの機能に含まれていません。 "コンパイラーは、主コンストラクター*:で宣言されたすべてのプロパティーから次のメンバーを自動的に派生させます。" (それを指摘してくれたkotlinglang slackコミュニティに感謝します) –

関連する問題