为什么在 scala.language.implicitConversions 不是最后一次导入时发出警告?
Why warning when scala.language.implicitConversions is not the last import?
在我的 Scala 代码中,我有一些隐式转换,并且我有必要的导入:
import scala.language.implicitConversions
但是,有时当在此之后完成另一个导入时,我会收到警告,好像导入根本不存在:
Warning:(112, 18) implicit conversion method pair2Dimension should be enabled
by making the implicit value scala.language.implicitConversions visible.
build.sbt:
name := "ImplicitSBT"
version := "1.0"
scalaVersion := "2.11.5"
scalacOptions ++= Seq("-deprecation","-feature")
libraryDependencies += "org.scala-lang.modules" %% "scala-swing" % "1.0.1"
Main.scala:
import scala.language.implicitConversions
import scala.swing.{Action, _}
object Main extends App {
implicit def pair2Dimension(pair: (Int, Int)): Dimension = new Dimension(pair._1, pair._2)
val dim : Dimension = (0,0)
println(dim)
}
为什么会这样? import scala.swing.{Action, _}
如何隐藏 implicitConversions
导入?
How is import scala.swing.{Action, _} hiding the implicitConversions import?
你的:
import scala.language.implicitConversions
... 在 scala.swing
包对象中被 implicitConversions
defined 隐藏:
package scala
...
package object swing {
...
implicit lazy val implicitConversions = scala.language.implicitConversions
...
}
由于您在此处使用通配符导入:
import scala.swing.{Action, _}
... scala.swing.implicitConversions
从 scala.swing
导入,最后阴影 scala.language.implicitConversions
.
有趣的问题是:如果有两个 "feature flags"(在本例中为 implicitConversions
),为什么 scalac
无法确定语言功能已启用,一个在同级别。
这可能是一个错误以及 SIP 18 实现方式的细节。
无论如何,要解决这个问题,我建议您执行以下操作之一:
不要导入scala.language.implicitConversions
(因为通配符导入时已经导入了scala.swing
)
不要从 scala.swing
导入通配符(不要污染你的范围,而是导入你需要的)
在您的 Main
对象级别
对 implicitConversions
进行另一次导入(不被另一个隐藏)
这是隐式查找中的错误。
这是更普通代码中的相同结构,其中所需的隐式是执行上下文。
(通配符导入是否来自包对象,或者其他包是否在同一个编译单元中都无关紧要。)
由于代码使用显式 global
进行编译,因此应该使用隐式 arg 进行编译。
如果隐式可以是 accessed without a prefix。
binding precedence不受源代码顺序的影响。阴影以通常的方式工作;绑定永远不会影响更高优先级的绑定。
/*
package object bound2 {
implicit lazy val global = scala.concurrent.ExecutionContext.Implicits.global
}
*/
package bound2 {
object B {
implicit lazy val global: concurrent.ExecutionContextExecutor = scala.concurrent.ExecutionContext.global
}
}
package bound {
// the order of these imports in the same scope should not matter
import scala.concurrent.ExecutionContext.Implicits.global
import bound2.B._
object Test extends App {
val f = concurrent.Future(42) //(global) // explicit arg works
Console println concurrent.Await.result(f, concurrent.duration.Duration.Inf)
}
}
在规范示例 2.0.1 中,添加标记为 "OK" 的行可以编译,您可以验证顺序无关紧要,但它在内部范围内变得不明确,因为 "wildcard y"没有从外部范围隐藏 "explicit y":
import X.y // `y' bound by explicit import
println("L16: "+y) // `y' refers to `Q.X.y' here
import P.X._
println("OK: "+y) // `y' refers to `Q.X.y' here
locally { val x = "abc" // `x' bound by local definition
import P.X._ // `x' and `y' bound by wildcard import
// println("L19: "+y) // reference to `y' is ambiguous here
如
中所述
http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html
通配符导入(如您所写)为任何 Swing 隐式定义提供了相当高的优先级,这显然隐藏了您的优先级。
既然你是用SBT编译的,通过下面的设置岂不是更简单
scalacOptions ++= Seq(
"-feature",
"-language:implicitConversions"
)
不用再担心导入的正确位置是什么了scala.language.implicitConversions
?
在我的 Scala 代码中,我有一些隐式转换,并且我有必要的导入:
import scala.language.implicitConversions
但是,有时当在此之后完成另一个导入时,我会收到警告,好像导入根本不存在:
Warning:(112, 18) implicit conversion method pair2Dimension should be enabled by making the implicit value scala.language.implicitConversions visible.
build.sbt:
name := "ImplicitSBT"
version := "1.0"
scalaVersion := "2.11.5"
scalacOptions ++= Seq("-deprecation","-feature")
libraryDependencies += "org.scala-lang.modules" %% "scala-swing" % "1.0.1"
Main.scala:
import scala.language.implicitConversions
import scala.swing.{Action, _}
object Main extends App {
implicit def pair2Dimension(pair: (Int, Int)): Dimension = new Dimension(pair._1, pair._2)
val dim : Dimension = (0,0)
println(dim)
}
为什么会这样? import scala.swing.{Action, _}
如何隐藏 implicitConversions
导入?
How is import scala.swing.{Action, _} hiding the implicitConversions import?
你的:
import scala.language.implicitConversions
... 在 scala.swing
包对象中被 implicitConversions
defined 隐藏:
package scala
...
package object swing {
...
implicit lazy val implicitConversions = scala.language.implicitConversions
...
}
由于您在此处使用通配符导入:
import scala.swing.{Action, _}
... scala.swing.implicitConversions
从 scala.swing
导入,最后阴影 scala.language.implicitConversions
.
有趣的问题是:如果有两个 "feature flags"(在本例中为 implicitConversions
),为什么 scalac
无法确定语言功能已启用,一个在同级别。
这可能是一个错误以及 SIP 18 实现方式的细节。
无论如何,要解决这个问题,我建议您执行以下操作之一:
不要导入
scala.language.implicitConversions
(因为通配符导入时已经导入了scala.swing
)不要从
scala.swing
导入通配符(不要污染你的范围,而是导入你需要的)在您的
Main
对象级别 对
implicitConversions
进行另一次导入(不被另一个隐藏)
这是隐式查找中的错误。
这是更普通代码中的相同结构,其中所需的隐式是执行上下文。
(通配符导入是否来自包对象,或者其他包是否在同一个编译单元中都无关紧要。)
由于代码使用显式 global
进行编译,因此应该使用隐式 arg 进行编译。
如果隐式可以是 accessed without a prefix。
binding precedence不受源代码顺序的影响。阴影以通常的方式工作;绑定永远不会影响更高优先级的绑定。
/*
package object bound2 {
implicit lazy val global = scala.concurrent.ExecutionContext.Implicits.global
}
*/
package bound2 {
object B {
implicit lazy val global: concurrent.ExecutionContextExecutor = scala.concurrent.ExecutionContext.global
}
}
package bound {
// the order of these imports in the same scope should not matter
import scala.concurrent.ExecutionContext.Implicits.global
import bound2.B._
object Test extends App {
val f = concurrent.Future(42) //(global) // explicit arg works
Console println concurrent.Await.result(f, concurrent.duration.Duration.Inf)
}
}
在规范示例 2.0.1 中,添加标记为 "OK" 的行可以编译,您可以验证顺序无关紧要,但它在内部范围内变得不明确,因为 "wildcard y"没有从外部范围隐藏 "explicit y":
import X.y // `y' bound by explicit import
println("L16: "+y) // `y' refers to `Q.X.y' here
import P.X._
println("OK: "+y) // `y' refers to `Q.X.y' here
locally { val x = "abc" // `x' bound by local definition
import P.X._ // `x' and `y' bound by wildcard import
// println("L19: "+y) // reference to `y' is ambiguous here
如
中所述http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html
通配符导入(如您所写)为任何 Swing 隐式定义提供了相当高的优先级,这显然隐藏了您的优先级。
既然你是用SBT编译的,通过下面的设置岂不是更简单
scalacOptions ++= Seq(
"-feature",
"-language:implicitConversions"
)
不用再担心导入的正确位置是什么了scala.language.implicitConversions
?