2

ダックタイピングに使用するタイプがあります。

type t={
   def x:Int
 ...
}
class t2 {
 def x:Int=1
}
def myt:t=new t2 //ducktyping

タイプをインターフェースするように強制されるトレイトを書きたいのですが、これは機能しません:

trait c extends t { //interface DOES NOT COMPILE
  def x:Int=1
}

一方、タイプtの代わりにトレイトt1を書くと、ダックタイピング機能が失われます。

trait t1 {
 def x:Int
}
type t=t1
trait c extends t1 { // t1 can be used as interface
  def x:Int=1
}
def myt:t=new t2  // DOES NOT COMPILE since t1 is expected

では、ダックタイピングとインターフェースの両方をどのように使用できますか?

4

1 に答える 1

4

Scala ではクラスのようなエンティティ (つまり、クラス、トレイト、Java インターフェイス) のみを拡張できますが、一般的な型 (つまり、構造型、型パラメーター、またはメンバー) は拡張できません。ただし、これらすべてに自己入力できます。つまりtrait c、次のように非コンパイルを書き換えることができます。

trait c { self : t =>
  def x : Int = 1
}

cの型の本体内では、 が であるthisことがわかっていますt。つまり、構造型 に準拠していることがわかっており、その構造型に実際に準拠しているクラス{ def x : Int }にのみ混在cさせることができます (署名を直接実装することによって)。または、abstract の場合は、self-type を再アサートし、義務を最終的な具象クラスに伝播することによって)、

type t = { def x : Int }

trait c { self : t => }

class t2 extends c {  // OK, t2 conforms to t
  def x : Int = 1
}

def myt : t = new t2  // OK, as before

class t3 extends c {  // Error: t3 doesn't conform to c's self-type
  def y : String = "foo"
}
于 2012-03-15T15:53:40.187 に答える