4

TraversableOnceには、sum含まれている型が である場合にのみ使用できるメソッドがありNumericます (それ以外の場合はコンパイルされません)。これは他のケースでも使用できるのでしょうか (実行時チェックを回避するため)。

特に、2 つのトレイト A と B がある場合です。オブジェクトが A と B の両方fを継承する場合にのみ使用できるメソッドが必要ですが、一方だけを継承する場合はそうではありません。もう作りたくない。両方の特性が継承されていない場合は使用できないようにしたいだけです。trait AB extends A with Bf

package com.example

trait Base
trait Foo extends Base {
  def g = println("foo bar " + toString)
}
trait Bar extends Base {
  /* If this is both Foo and Bar, I can do more */
  def f = {
    if (!this.isInstanceOf[Foo]) error("this is not an instance of Foo")
    this.asInstanceOf[Foo].g
  }
}
object Test {
  def main(args: Array[String]): Unit = {
    object ab extends Foo with Bar
    object ba extends Bar with Foo
    object b extends Bar
    ab.f
    ba.f
    // I don't want next line to compile:
    try { b.f } catch { case e: RuntimeException => println(e) }
  }
}

編集:@Aaron Novstrupのおかげで解決策

trait Bar extends Base { self =>
  def f(implicit ev: self.type <:< Foo) = {
    //self.asInstanceOf[Foo].g // [1]
    ev(this).g // [2]
  }
}

mainでは、コンパイルされb.fません。良い

EDIT 2: 行 [1] を [2] に変更し、@Aaron Novstrup による回答の変更を反映

編集 3: self@Aaron Novstrup による回答の反映変更を使用せずに

trait Bar extends Base {
  /* If this is both Foo and Bar, I can do more */
  def f(implicit ev: this.type <:< Foo) = {
    ev(this).g
  }
}
4

2 に答える 2

8

はい、次のことができます。

trait A {
   def bar = println("I'm an A!")
}

trait B { 
   def foo(implicit ev: this.type <:< A) = { 
      ev(this).bar
      println("and a B!")
   }
}

コンパイラはevidence、(呼び出しサイトでの) オブジェクトの静的型が extends である場合にのみ、パラメーターを提供できますA

于 2010-12-10T01:12:23.270 に答える
3

sum の署名が

def sum [B >: A] (implicit num: Numeric[B]) : B

数値型がNumericを拡張すると想定しているようですが、これは正しくありません。実際には、これらは暗黙的にNumericに変換されます。 Intの場合、使用される暗黙的なものは、 plustimesなどの演算を定義するscala.math.Numeric.IntIsIntegralです。

したがって、TraversableOnce[A].sum が許可される A の型に関する制限は、必要な操作を暗黙的に提供することによって達成されます

これは、数値クラスと型クラスの全体的な仕組みを簡単に説明したものです。詳細については、math.Numeric.XisY、math.Integral、および math.Fractional のソースと、型クラスがどのように機能するかを確認してください: implicit-tricks-type-class-patternおよびtype-class-pattern-example

于 2010-12-10T01:29:19.443 に答える