2017-03-10 6 views
0

ここでは、コードを煮詰めた例を示します。抽象型のスカラ配列を使用する

trait DataType { 
    type DType 
    // more stuff 
} 

object IntType extends DataType { 
    type DType = Int 
    // more stuff 
} 

trait Codec { 
    val dtype: DataType 
    // more stuff 
} 

class DenseCodec(val dtype: DataType) extends Codec { 
    def get(size: Int) = new Array[dtype.DType](size) 
} 

val dense = new DenseCodec(IntType) 

dense.get(4) 

これはコンパイルされません。

cannot find class tag for element type DenseCodec.this.dtype.DType def get(size: Int) = new Array[dtype.DType](size) ^

を、私は、これはScalaでは配列は特別なものとは何かを持って知っています。私はここでVectorのようなものを使うことができますが、うまくいくでしょうが、私が取り組んでいるプロジェクトはデータ処理に重く、可能な限り効率的にしたいと考えています。

答えて

2

これは、あなたもテンプレートTDTypeを置き換えることができ

def get(size: Int)(implicit tag: ClassTag[DataType]) = new Array[DataType](size) 

を仕事や

def get[DType: ClassTag](size: Int) = new Array[DType](size) 

バインド同等のコンテキストを使用します。

Array'sコンストラクタは、実際にタイプClassTagの暗黙のパラメータを取り、したがって、あなたは、暗黙的または明示的に、1つを指定する必要があります。

EDIT:dtypeは具体的なDTypeだけ抽象的なものを持っていないタイプDataTypeであるためdtype.DTypeを使用して動作しないことも注目に値します。おかしいほどdtype.typeは、実行時にval dtype: DataTypeがすでにIntTypeであるため、うまく動作します。

EDIT2:型を継承したい場合は、型クラスを使用する唯一の方法であることが怖いです。

import scala.reflect.ClassTag 

object Types { 
    trait DataType[A] { 
    // more stuff 
    } 

    object IntType extends DataType[Int] 

    object StringType extends DataType[String] 

    trait Codec[B] { 
    val dtype: DataType[B] 
    // more stuff 
    } 

    class DenseCodec[B](val dtype: DataType[B]) extends Codec[B] { 
    def get(size: Int)(implicit ct: ClassTag[B]) = new Array[B](size) 
    } 

    def main(args: Array[String]): Unit = { 
    val denseInt = new DenseCodec(IntType) 
    val arrInt = denseInt.get(4) //Array[Int] 

    val denseString = new DenseCodec(StringType) 
    val arrString = denseString.get(4) //Array[String] 
    } 
} 

あなたがDTypeを取り除く、代わりに型クラスの型を使用することができますこの方法です。あなたはIntTypeとおそらくより多くの型を定義したいので、定型文を導入しないでください。 希望これはあなたの問題を解決:)

EDIT3:あなただけ

trait DataType[A] { 
    type DType = A 
    // more stuff 
} 

で行くとget定義

def get(size: Int)(implicit ct: ClassTag[B]) = new Array[dtype.DType](size) 

しかし、あなたが持っているでしょうこの方法を変更し、あなたのDTypeを維持したい場合IntTypeStringTypeなどから得られるロングタイプのシグネチャ

+0

'dense.get(4)'は配列[Notヒンジ]。それは私が 'dense [IntType.DType] .get(4)'を実行するとうまくいくが、それは余分に見える。 –

+0

もちろん、 'DType'は単なるエイリアスです。この場合、あなたが定義する各クラスに定義されています。 'IntType'。自分でタイプ階層を導入することはありません。 'IntType.DType'は、コンパイル時に' Int'と言うだけの素晴らしい方法です。 – sebszyller

+0

答えが更新されました。 @marcin_koss – sebszyller

関連する問題