Scala 通配符导入,然后隐藏特定的隐式?

Scala 通配符导入,然后隐藏特定的隐式?,scala,implicit,Scala,Implicit,给定具有2个隐式的以下对象: scala> object Foo { | implicit def stringToInt(x: String) = 555 | implicit def stringToBoolean(x: String) = true | } warning: there were two feature warnings; re-run with -feature for details defined object Foo 我可以

给定具有2个隐式的以下对象:

scala> object Foo {
     |  implicit def stringToInt(x: String) = 555
     |  implicit def stringToBoolean(x: String) = true
     | }
warning: there were two feature warnings; re-run with -feature for details
defined object Foo
我可以使用它们:

scala> def f(x: Int) = x
f: (x: Int)Int

scala> import Foo._
import Foo._

scala> f("asdf")
res0: Int = 555

scala> def g(b: Boolean) = b
g: (b: Boolean)Boolean

scala> g("asdfasdf")
res1: Boolean = true
然后,我尝试禁用
stringToInt
implicit

scala> import Foo.{stringToInt => _}
import Foo.{stringToInt=>_}
但是,显然,这是行不通的

scala> f("adsfasdf")
res2: Int = 555
通配符导入隐式后,是否可以隐藏它们

基本上,我想使用所有
Foo
的隐式,减去一个
stringToInt


注意-当然,我可以简单地只导入Foo.stringToBoolean,但是在我的场景中,
Foo
有25个导入,我想使用其中的24个。因此,更简洁的做法是使用all,然后减去一。

REPL只是近似于从历史中导入什么,而一种近似方法总是使用导入的隐式

在普通代码中,可以通过隐藏标识符来禁用隐式

最佳选择是:

scala> object X { val stringToInt = 0 }
defined object X

scala> import X._
import X._

scala> f("asdf")
<console>:20: error: type mismatch;
 found   : String("asdf")
 required: Int
       f("asdf")
         ^

想法是将阴影变量引入当前行的REPL模板范围。

现有语法不允许特定导入。它是用于重命名/别名导入的语法的扩展:

import scala.collection.concurrent.{ Map => CMap } // Import concurrent Map, but alias it to "CMap", so the predef-imported "Map" isn't shadowed.
要隐藏导入,可以将其别名为“\u1”:

类似地,要导入除特定条目外的所有对象,请使用:

import Foo.{ stringToInt => _, _ }

scala> def g(b: Boolean) = b
g: (b: Boolean)Boolean

scala> g("asdfasdf")
res1: Boolean = true

scala> def f(x: Int) = x
f: (x: Int)Int

scala> f("asdf")
<console>:13: error: type mismatch;
 found   : String("asdf")
 required: Int
              f("asdf")
                ^
import Foo.{stringToInt=>
scala>def g(b:Boolean)=b
g:(b:布尔)布尔
scala>g(“asdfasdf”)
res1:Boolean=true
scala>def(x:Int)=x
f:(x:Int)Int
scala>f(“asdf”)
:13:错误:类型不匹配;
找到:字符串(“asdf”)
必填项:Int
f(“asdf”)
^

有一个旧的PR,用于按照您想要的方式隔离导入,所以也许有一天该设施会到达。啊,不要使用通配符导入。对它们有不同的看法,但我认为它们是非常糟糕的风格。首先是因为你这里的问题。当您使用非平凡类型时,这些类型的问题可能非常微妙。其次,如果没有IDE,代码库很难理解。虽然IDE对某些人来说是一个有用的工具,但它并不是一个普遍采用的工具,而且您可以有效地限制选择不使用IDE的开发人员的数量。@Scala中隐式的通配符导入是相当标准的样式,例如
JavaConverters.\u
。没有一个理智的人会试图列举它们。我对这个标准感到遗憾。JavaConverters是一个简单的例子。您不需要逐一列举。您只需导入所需的一两个。我知道在某些情况下,通配符导入是dsl工作所必需的。否则,这种风格不利于可读性,引入了微妙的bug,并且在非常特殊的情况下似乎只有有限的好处。FTR,这不是问题所在(尽管OP显然同意你的观点)。一旦你在REPL中进行通配符导入,除非你解决它,否则你将失败。@Shadowlands-谢谢你的帮助回答,+1。然而,我轻率地接受了你对我问题的回答。我最终用你的解决方案来解决我的问题,但是,我相信我接受我问题的答案是公平的。@KevinMeredith没关系,很高兴能帮上忙。
import scala.collection.mutable.{ Map, TrieMap => _ } // Import Map, but not TrieMap
import Foo.{ stringToInt => _, _ }

scala> def g(b: Boolean) = b
g: (b: Boolean)Boolean

scala> g("asdfasdf")
res1: Boolean = true

scala> def f(x: Int) = x
f: (x: Int)Int

scala> f("asdf")
<console>:13: error: type mismatch;
 found   : String("asdf")
 required: Int
              f("asdf")
                ^