7

型エイリアスを記述して、簡潔で適切なカプセル化された Scala コードを作成したいと考えています。値がタプルであるマップのリストであるというプロパティを持つコレクションを取得したとします。私の型は のようなものList[Map[Int, (String, String)]]、または私のアプリケーションが許可するより一般的なものを書きます。Seq[MapLike[Int, Any]]具象サブクラスがより具体的で、私のボートを浮かせる何かを要求するスーパータイプを持つことを想像できます。

次に、この長い型のエイリアスを書きたいと思います。

class ConcreteClass {
  type DataType = List[Map[Int, (String, String)]]
  ...
}

ConcreteClass#DataTypeそれから、私はそれを持って行けるところならどこでも喜んで使用し、それを使用します.

ここで、関数を追加するとします

def foo(a : DataType) { ... }

そして、空のリストで外部から呼び出したい。を呼び出すことはできますfoo(List())が、基になる型を の別の型に変更したい場合はSeq、戻ってこのコードも変更する必要があります。さらに、この空のリストが として意図されていることはあまり明示的ではありませんDataType。また、コンパニオン オブジェクトには関連付けられたメソッドがないため、 、またはListを呼び出すことはできません。この長い型の重要な部分を書き出さなければならないので、空でないリストが必要な場合はさらに面倒です。DataType()DataType.empty

コードを短縮してブラックボックス化するために、Scala に自分の型 (作成者メソッドを含むコンパニオン オブジェクトを含む) を同じものとして理解させる方法はありますか? または、そもそもこれを行うべきではない理由はありますか?

4

2 に答える 2

7

答えは実際には非常に簡単でした:

class ConcreteClass {
  type DataType = List[String]
}
object ConcreteClass {
  val DataType = List
}
val d = ConcreteClass.DataType.empty

これにより、私のコードで ConcreteClass.DataType を呼び出して、List 内のすべてのメソッドを含むリストを構築することができます。

洞察をくれたオレグに感謝します。彼の答えは、ConcreteClass.DataType への呼び出しを List に委譲したくないが、呼び出し元に許可したいことを正確に制御したい場合にも最適です。

于 2010-10-13T04:47:43.417 に答える
5

これはどうですか?

class ConcreteClass {
  type DataType = List[String]
}
object DataType {
  def apply(): ConcreteClass#DataType = Nil
}
//...
val a = DataType()

于 2010-10-13T04:26:00.647 に答える