首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当scala.language.implicitConversions不是最后一个导入时,为什么要发出警告?

当scala.language.implicitConversions不是最后一个导入时,为什么要发出警告?
EN

Stack Overflow用户
提问于 2015-01-14 11:42:37
回答 3查看 7.6K关注 0票数 8

在我的Scala代码中,我有一些隐式转换,并且我有必要的导入礼物:

代码语言:javascript
复制
import scala.language.implicitConversions

但是,有时当在此之后执行另一个导入时,我会收到警告,好像根本没有导入一样:

警告:(112,18)隐式转换方法pair2Dimension应该通过使隐式值scala.language.implicitConversions可见来启用。

build.sbt:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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导入的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-03-02 16:52:36

导入scala.swing.{Action,_}如何隐藏implicitConversions导入?

你的:

代码语言:javascript
复制
import scala.language.implicitConversions

..。获取implicitConversions 已定义scala.swing包对象中的阴影:

代码语言:javascript
复制
package scala

...

package object swing {

...

implicit lazy val implicitConversions = scala.language.implicitConversions

...

}

由于您在这里使用通配符导入:

代码语言:javascript
复制
import scala.swing.{Action, _}

. scala.swing.implicitConversions是从scala.swing导入的,最后是阴影scala.language.implicitConversions

有趣的问题是:如果有两个“特性标志”(在本例中是implicitConversions),一个标记在同一级别上,那么为什么implicitConversions无法确定是否启用了语言特性。

这可能是一个bug,也可能是如何实现SIP 18的具体细节。

无论如何,为了解决这个问题,我建议您做以下工作之一:

  1. 不要导入scala.language.implicitConversions (因为在通配符导入scala.swing时已经导入了)
  2. 不要从scala.swing进行通配符导入(不要污染您的范围并导入所需的内容)
  3. implicitConversions对象级别执行另一个Main导入(而不是由另一个导入)
票数 5
EN

Stack Overflow用户

发布于 2015-07-22 22:19:57

如上文所述

http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

通配符导入(如您所写)为任何Swing隐式定义赋予了相当高的优先级,这显然隐藏了您的定义。

既然您正在使用SBT进行编译,那么通过下面的设置不是更容易吗?

代码语言:javascript
复制
scalacOptions ++= Seq(
  "-feature",
  "-language:implicitConversions"
)

别再担心什么地方可以导入scala.language.implicitConversions

票数 6
EN

Stack Overflow用户

发布于 2015-03-08 13:46:47

这是隐式查找中的一个bug。

下面是更普通代码中的相同结构,其中所需的隐式是执行上下文。

(通配符导入是否来自package对象,或者其他包是否在同一个编译单元中,都无关紧要。)

由于代码使用显式global进行编译,所以应该使用隐式arg进行编译。

如果隐式可以是访问时没有前缀,则它是可用的。

约束优先不受源代码顺序的影响。阴影以通常的方式工作;绑定永远不会掩盖更高优先级的绑定。

代码语言:javascript
复制
/*
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)
  }
}

在spec示例2.0.1中,添加标记为"OK“的行进行编译,您可以验证顺序并不重要,但在内部范围内变得不明确,因为”通配符y“不隐藏外部作用域的”显式y“:

代码语言:javascript
复制
    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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27942143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档