简体   繁体   English

为什么这种隐式转换是非法的?

[英]Why this type of implicit conversion is illegal?

I write the following implicit conversion in scala: 我在scala中编写以下隐式转换:

  implicit def strToInt2(str: String):Int = {
    str.toInt
  }

But it rises this compilation error: 但它上升了这个编译错误:

<console>:9: error: type mismatch;
 found   : str.type (with underlying type String)
 required: ?{val toInt: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method augmentString in object Predef of type (x: String)scala.collection.
immutable.StringOps
 and method toi in object $iw of type (str: String)Int
 are possible conversion functions from str.type to ?{val toInt: ?}
           str.toInt
           ^

If I remove the return type, just declare it like this: 如果我删除了返回类型,只需声明它:

  implicit def strToInt2(str: String) = {
    str.toInt
  }

It compiles successfully. 它编译成功。 Can anyone tell me what's the difference between the two ? 谁能告诉我两者之间有什么区别?

Ok, let's start with the beginning, why does it fail in the first case: 好吧,让我们从头开始,为什么在第一种情况下失败:

  1. You try to define an implicit method that transforms a String into an Int and to do so you call toInt . 您尝试定义一个将String转换为Int的隐式方法,并执行此操作以调用toInt
  2. Unfortunately, toInt is not a part of the String class. 不幸的是, toInt不是String类的一部分。 Thus, the compiler needs to find an implicit to convert str in something that has a toInt:Int method. 因此,编译器需要在具有toInt:Int方法的内容中找到隐式转换str
  3. Fortunately, Predef.augmentString convert a String into a StringOps , which has such a method. 幸运的是, Predef.augmentStringString转换为StringOps ,它具有这样的方法。
  4. But the Int type also have such a method and AS you define a return type, the method strToInt2 can be called recursively, and as the method is implicit, it can be applied to transform something with a toInt:Int function. Int类型也有这样的方法和AS你定义一个返回类型,方法strToInt2可以递归调用,并且由于该方法是隐式的,它可以应用于使用toInt:Int函数转换某些东西。
  5. The compiler doesn't know which implicit method to use (between yours and Predef.augmentString and throws an error. 编译器不知道使用哪个隐式方法(在您和Predef.augmentString之间)并抛出错误。

In the second case, as you omit the return type, the strToInt2 function cannot be recursive, and there are no longer two candidates to transform the String . 在第二种情况下,当您省略返回类型时, strToInt2函数不能递归,并且不再有两个候选者来转换String

BUT if after this definition, you try: "2".toInt , the error is back: you now have two ways to obtain something with a toInt:Int function when you have a String . 但是如果在这个定义之后,你尝试: "2".toInt ,错误又回来了:当你有一个String时,你现在有两种方法可以获得带有toInt:Int函数的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM