0

クラスコンストラクターに一致する構造化型 ins scala を作成することは可能ですか (クラス内のメソッド/関数定義とは対照的に)

クラスのメソッド呼び出しを通常一致させるには、次のようにします。

type SomeType : {def someMethod:String}

これにより、次のようなメソッドを作成できます

someMethod(a:SomeType) = {
    println(a.someMethod)
}

このようなものに相当するものは何ですか

type AnotherType: {.......}

このようなもので動作します

class UserId(val id:Long) extends AnyVal

だから、あなたはこのようなことをすることができます

anotherMethod(a:AnotherType,id:Long):AnotherType = {
    new a(id)
}

anotherMethod(UserId,3) // Will return an instance of UserId(3)

これは、runtimeClass と getConstructors を使用したマニフェストを使用して可能であると考えていますが、(構造化された型のようなものを使用して) もっときれいに使用できるかどうか疑問に思っています。

4

1 に答える 1

4

リフレクションまたは構造型の代わりに、型コンパニオン オブジェクトを関数値として使用することを検討してください。

scala> case class UserId(val id: Long) extends AnyVal
defined class UserId

scala> def anotherMethod[T, U](ctor: T => U, t: T) = ctor(t)
anotherMethod: [T, U](ctor: T => U, t: T)U

scala> anotherMethod(UserId, 3L)
res0: UserId = UserId(3)

これは、ケース クラスで示されているように機能します。これは、Scala コンパイラがapplyクラスのプライマリ コンストラクターを呼び出すメソッドをコンパニオン オブジェクトに自動的に提供し、コンパニオンが適切なFunctionNトレイトを拡張するように手配するためです。

なんらかの理由で型をケース クラスにできない場合は、apply メソッドを自分で提供できます。

object UserId extends (Long => UserId) {
  def apply(l: Long) = new UserId(l)
}

または、代わりに呼び出しサイトで関数リテラルを使用できます。

anotherMethod(new UserId(_: Long), 3L)
于 2013-08-26T12:38:09.690 に答える