簡體   English   中英

為什么在這種情況下隱式轉換不起作用?

[英]Why doesn't implicit conversion work in this case?

我在Scala中有以下代碼。 假設有一個A到B的隱式轉換。為什么我的隱式List [A]到List [B]轉換不起作用?

object ImplicitTest {    
  case class CaseClassA(a: String)
  case class CaseClassB(b: String)

  implicit def a2b(a: CaseClassA): CaseClassB = CaseClassB(a.a)

  implicit def listImplicitConversion[A, B](l: List[A])(implicit conv: A => B): List[B] = l.map(conv)

  def main(args: Array[String]) {
    val listOfA: List[CaseClassA] = List(CaseClassA("a"))
    val listOfB: List[CaseClassB] = listOfA
  }
}

編譯此代碼會導致以下錯誤:

Error:(14, 37) type mismatch;
 found   : List[ImplicitTest.CaseClassA]
 required: List[ImplicitTest.CaseClassB]
    val listOfB: List[CaseClassB] = listOfA

這是一個錯誤,即SI-10405 ,我前段時間開過。

出於某種原因, Predef導致隱式搜索失敗。 如果使用-Yno-predef標志編譯代碼,那么您將成功。

症狀是你在-Xlog-implicits下編譯時看到Predef.conforms[A]試圖解析隱式的Predef.conforms[A]

λ scalac -Xlog-implicits Bar.scala
Bar.scala:16: listImplicitConversion is not a valid implicit value for List[yuval.tests.ImplicitTest.CaseClassA] => List[yuval.tests.ImplicitTest.CaseClassB] because:
incompatible: (l: List[yuval.tests.ImplicitTest.CaseClassA])(implicit conv: yuval.tests.ImplicitTest.CaseClassA => yuval.tests.ImplicitTest.CaseClassA)List[yuval.tests.ImplicitTest.CaseClassA] does not match expected type List[yuval.tests.ImplicitTest.CaseClassA] => List[yuval.tests.ImplicitTest.CaseClassB]
    val listOfB: List[CaseClassB] = listOfA

並忽略任何進一步的搜索,雖然它之前成功匹配:

|-- List[CaseClassB] TYPEmode (site: value listOfB in ImplicitTest)
|    |    |    |    |    |-- scala.`package` EXPRmode-POLYmode-QUALmode (site: value listOfB in ImplicitTest)
|    |    |    |    |    |    \-> scala.type
|    |    |    |    |    |-- CaseClassB TYPEmode (site: value listOfB in ImplicitTest)
|    |    |    |    |    |    \-> yuval.tests.ImplicitTest.CaseClassB
|    |    |    |    |    \-> List[yuval.tests.ImplicitTest.CaseClassB]
|    |    |    |    |-- listOfA : pt=List[yuval.tests.ImplicitTest.CaseClassB] BYVALmode-EXPRmode (site: value listOfB in ImplicitTest)
|    |    |    |    |    [search #2] start `List[yuval.tests.ImplicitTest.CaseClassA]`, searching for adaptation to pt=List[yuval.tests.ImplicitTest.CaseClassA] => List[yuval.tests.ImplicitTest.CaseClassB] (silent: value listOfB in ImplicitTest) implicits disabled
|    |    |    |    |    [search #2] considering listImplicitConversion
|    |    |    |    |    |-- listImplicitConversion BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value listOfB in ImplicitTest) implicits disabled
|    |    |    |    |    |    [adapt] [A, B](l: List[A])(implicit conv: A => B)List[B] adapted to [A, B](l: List[A])(implicit conv: A => B)List[B]
|    |    |    |    |    |    \-> (l: List[A])(implicit conv: A => B)List[B]
|    |    |    |    |    solving for (A: ?A, B: ?B)
|    |    |    |    |    [search #3] start `[A, B](l: List[A])(implicit conv: A => B)List[B]` inferring type B, searching for adaptation to pt=yuval.tests.ImplicitTest.CaseClassA => B (silent: value listOfB in ImplicitTest) implicits disabled
|    |    |    |    |    [search #3] considering a2b
|    |    |    |    |    |-- { ((a: yuval.tests.ImplicitTest.CaseClassA) => ImplicitTe... : pt=yuval.tests.ImplicitTest.CaseClassA => ? EXPRmode (silent: value listOfB in ImplicitTest) implicits disabled
|    |    |    |    |    |    |-- ((a: yuval.tests.ImplicitTest.CaseClassA) => ImplicitTest... : pt=yuval.tests.ImplicitTest.CaseClassA => ? EXPRmode (silent: value listOfB in ImplicitTest) implicits disabled
|    |    |    |    |    |    |    |-- ImplicitTest.this.a2b(a) EXPRmode (silent: value $anonfun in ImplicitTest) implicits disabled
|    |    |    |    |    |    |    |    |-- ImplicitTest.this.a2b BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value $anonfun in ImplicitTest) implicits disabled
|    |    |    |    |    |    |    |    |    \-> (a: yuval.tests.ImplicitTest.CaseClassA)yuval.tests.ImplicitTest.CaseClassB
|    |    |    |    |    |    |    |    |-- a : pt=yuval.tests.ImplicitTest.CaseClassA BYVALmode-EXPRmode (silent: value $anonfun in ImplicitTest) implicits disabled
|    |    |    |    |    |    |    |    |    \-> yuval.tests.ImplicitTest.CaseClassA
|    |    |    |    |    |    |    |    \-> yuval.tests.ImplicitTest.CaseClassB
|    |    |    |    |    |    |    \-> yuval.tests.ImplicitTest.CaseClassA => yuval.tests.ImplicitTest.CaseClassB
|    |    |    |    |    |    \-> yuval.tests.ImplicitTest.CaseClassA => yuval.tests.ImplicitTest.CaseClassB
|    |    |    |    |    [adapt] a2b adapted to { ((a: yuval.tests.ImplicitTest.CaseClassA) => ImplicitTe... based on pt yuval.tests.ImplicitTest.CaseClassA => B
|    |    |    |    |    [search #3] solve tvars=?B, tvars.constr= >: yuval.tests.ImplicitTest.CaseClassB
|    |    |    |    |    solving for (B: ?B)
|    |    |    |    |    [search #3] success inferred value of type yuval.tests.ImplicitTest.CaseClassA => =?yuval.tests.ImplicitTest.CaseClassB is SearchResult({
|    |    |    |    |      ((a: yuval.tests.ImplicitTest.CaseClassA) => ImplicitTest.this.a2b(a))
|    |    |    |    |    }, TreeTypeSubstituter(List(type B),List(yuval.tests.ImplicitTest.CaseClassB)))

如果您害怕所有輸出,這是相關部分:

[search #3] success inferred value of type yuval.tests.ImplicitTest.CaseClassA => =?yuval.tests.ImplicitTest.CaseClassB is SearchResult({
  ((a: yuval.tests.ImplicitTest.CaseClassA) => ImplicitTest.this.a2b(a))
}, TreeTypeSubstituter(List(type B),List(yuval.tests.ImplicitTest.CaseClassB)))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM