Scala不用`=>排除隐式导出_` sytnax

时间:2017-11-29 08:40:42

标签: scala importerror implicit

根据this question和scala语言规范,可以使用以下语法排除导入: import java.{xxx => _, _}

然而,我发现这并不适用于暗示。例如:

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

scala> import schema.Encoder.{ofGeneric => _, _}
import schema.Encoder.{ofGeneric=>_, _}

根据规范,该成员无法访问:

scala> ofGeneric
<console>:15: error: not found: value ofGeneric
       ofGeneric
       ^

但是,处于隐式范围,我可以隐式访问它:

scala> :implicits
/* 10 implicit members imported from schema.Encoder */
  /* 10 defined in schema.Encoder */
  implicit val ofBoolean: Boolean]
  implicit def ofConcreteElem[K <: Symbol, A](implicit witness: shapeless.Witness.Aux[K],i
mplicit E: A]): shapeless.labelled.FieldType[K,A]]
  implicit val ofDateTime: java.time.OffsetDateTime]
  implicit val ofDouble: Double]
  implicit def ofElem[K <: Symbol, A, C[_]](implicit witness: shapeless.Witness.Aux[K],imp
licit E: shapeless.Lazy[A]],implicit C: cats.Foldable[C]): shapeless.labelled.FieldType[K,
C[A]]]
  implicit def ofGeneric[A, L <: shapeless.HList](implicit G: shapeless.LabelledGeneric.Au
x[A,L],implicit HE: shapeless.Lazy[L]]): A]
  implicit def ofHListSeq[K <: Symbol, H, T <: shapeless.HList](implicit witness: shapeles
s.Witness.Aux[K],implicit HE: shapeless.Lazy[shapeless.labelled.FieldType[K,H]]],implicit
TE: shapeless.Lazy[T]]): shapeless.labelled.FieldType[K,H] :: T]
  implicit val ofHNil: shapeless.HNil]
  implicit val ofInt: Int]
  implicit def ofString: String]

scala> implicitly[schema.Encoder[Tuple2[Int,String]]]
res3: schema.Encoder[(Int, String)] = schema.Encoder$$anonfun$ofGeneric$2@341619cc
                                                              ^^^^^^^^^

问题:

  1. 这是控制台中的错误还是语言功能?
  2. 有没有办法绕过这个(即导入除一个之外的所有隐式成员),而不单独指定每个函数?

2 个答案:

答案 0 :(得分:1)

来自规范:

  

有资格传递给隐式的实际参数   TT类型的参数分为两类。首先,符合条件的是全部   标识符xx,可以在方法调用点访问   ...... 如果没有   此规则下的符合条件的标识符,然后是第二个符合条件的标识符   属于隐式范围的某个对象的所有隐式成员   隐式参数的类型,TT。

     

TT类型的隐式范围包括所有的伴随模块   与隐式参数类型相关联的类。

所以,这就是说,一旦尝试查看本地范围,它会在伴随对象中寻找隐含。

确实可以通过调用上面的implicitly[...]表达式而不首先导入任何来看到这一点;它只是起作用,因为这些方法是伴侣的一部分。

根据上面的引用,这应该意味着如果我创建和/或导入一个隐含到与伴随对象中具有相同签名的范围,它们将优先,从而消除了“排除隐式导出”的需要'就像我原来的问题一样。

答案 1 :(得分:0)

不确定第一个问题,但解决方法是在范围内定义一个具有相同名称的非隐式成员。