Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this type of implicit conversion is illegal?

I write the following implicit conversion in 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 ?

like image 901
zjffdu Avatar asked Jan 30 '12 07:01

zjffdu


People also ask

Is implicit type conversion bad?

Implicit conversions allow the compiler to treat values of a type as values of another type. There's at least one set of scenarios in which this is unambiguously bad: non-total conversions. That is, converting an A to a B when there exists A s for which this conversion is impossible.

What is implicit type of conversion?

Overview. Implicit type conversion in C language is the conversion of one data type into another datatype by the compiler during the execution of the program. It is also called automatic type conversion.

What is implicit type conversion Why is it referred to as type promotion?

Implicit type of type conversion is also called as standard type conversion. We do not require any keyword or special statements in implicit type casting. Converting from smaller data type into larger data type is also called as type promotion.

What is the difference between implicit type conversion and implicit type conversion?

Implicit conversion is the conversion in which a derived class is converted into a base class like int into a float type. Explicit conversion is the conversion that may cause data loss. Explicit conversion converts the base class into the derived class.


1 Answers

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.
  2. Unfortunately, toInt is not a part of the String class. Thus, the compiler needs to find an implicit to convert str in something that has a toInt:Int method.
  3. Fortunately, Predef.augmentString convert a String into a StringOps, which has such a method.
  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.
  5. The compiler doesn't know which implicit method to use (between yours and Predef.augmentString and throws an error.

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.

BUT if after this definition, you try: "2".toInt, the error is back: you now have two ways to obtain something with a toInt:Intfunction when you have a String.

like image 105
Nicolas Avatar answered Oct 04 '22 17:10

Nicolas