2016-11-05 10 views
6

global実行コンテキストをインポートしてスコープ内に定義された暗黙の実行コンテキストを持つと、あいまいな暗黙的な結果になりますが、2.11ではうまく動作します。Scala 2.12の暗黙のExecutionContext優先度

import scala.concurrent._ 
import scala.concurrent.ExecutionContext.Implicits.global 

class A(implicit ec: ExecutionContext) { 
    x = implicitly[ExecutionContext] 
} 

コンパイラはエラーを与える:

error: ambiguous implicit values: 
both lazy value global in object Implicits of type => scala.concurrent.ExecutionContext 
and value ec in class A of type scala.concurrent.ExecutionContext 
match expected type scala.concurrent.ExecutionContext 
     val x = implicitly[ExecutionContext] 
         ^

この原因とどのようにコードでそれを回避するには何ですか?

+1

スカラ/スケーラの関連するコミットはhttps://github.com/scala/scala/commit/44953dcb08fc5dd92e423a56bd42bcc32757aaefであり、変更の正当性はhttps://issues.scala-lang.org/browse/SI-8849です。 –

+0

Viktor KlangはそのJIRAチケットについてコメントしています:ExecutionContext.globalを明示的に渡すか、必要に応じてそれを指す暗黙的なvalを導入することをお勧めします。 –

+0

2.11で問題が正しく理解されていれば、スコープ内の暗黙的に「グローバル」が選択されているため、予期せぬことに、そして、2.12では、この潜在的なプログラミングのミスをあいまいにすることで明らかにしています。リリースノートやドキュメントに言及する価値がありますか? – ochrons

答えて

2

この仕様では、クラスのメンバーの選択の曖昧さ回避として過負荷解決が処理されます。しかし、暗黙の解決は静的過負荷解決を使用してメンバーではない参照を選択します。

zzzyyy限りXから派生したクラスで定義されているので、おそらく、次は、仕様の誤解であるが、次のとおりです。

現在
$ scala 
Welcome to Scala 2.12.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_101). 
Type in expressions for evaluation. Or try :help. 

scala> import concurrent._, ExecutionContext.global 
import concurrent._ 
import ExecutionContext.global 

scala> trait X { implicit val xxx: ExecutionContext = global } 
defined trait X 

scala> class Y extends X { implicit val yyy: ExecutionContext = global ; def f = implicitly[ExecutionContext] } 
defined class Y 

scala> class Z extends X { def f(implicit zzz: ExecutionContext) = implicitly[ExecutionContext] } 
<console>:16: error: ambiguous implicit values: 
both value xxx in trait X of type => scala.concurrent.ExecutionContext 
and value zzz of type scala.concurrent.ExecutionContext 
match expected type scala.concurrent.ExecutionContext 
     class Z extends X { def f(implicit zzz: ExecutionContext) = implicitly[ExecutionContext] } 
                      ^

、あなたが囲むから暗黙的にシャドウ命名に依存しなければなりませんスコープ:

scala> class Z extends X { def f(implicit xxx: ExecutionContext) = implicitly[ExecutionContext] } 
defined class Z 

あるいは、

scala> :pa 
// Entering paste mode (ctrl-D to finish) 

package object p { import concurrent._ ; implicit val xxx: ExecutionContext = ExecutionContext.global } 
package p { import concurrent._ ; 
    class P { def f(implicit xxx: ExecutionContext) = implicitly[ExecutionContext] 
      def g = implicitly[ExecutionContext] } 
} 

// Exiting paste mode, now interpreting. 


scala> 
関連する問題