I write
object MyString {
implicit def stringToMyString(s: String) = new MyString(s)
}
class MyString(str: String) {
def camelize = str.split("_").map(_.capitalize).mkString
override def toString = str
}
object Parse {
def main(args: Array[String]) {
val x = "active_record".camelize
// ...
}
}
in my program. This causes a compiling error. After I inserted
import MyString.stringToMyString
Then it works.
From Odersky's Programming in Scala I got that implicit conversion in the companion object of the source or expected target types don't need to be imported.
An implicit conversion sequence is the sequence of conversions required to convert an argument in a function call to the type of the corresponding parameter in a function declaration. The compiler tries to determine an implicit conversion sequence for each argument.
An implicit conversion from type S to type T is defined by an implicit value which has function type S => T , or by an implicit method convertible to a value of that type. Implicit conversions are applied in two situations: If an expression e is of type S , and S does not conform to the expression's expected type T .
Implicit conversions in Scala are the set of methods that are apply when an object of wrong type is used. It allows the compiler to automatically convert of one type to another. Implicit conversions are applied in two conditions: First, if an expression of type A and S does not match to the expected expression type B.
Keyword explicit tells compiler to not use the constructor for implicit conversion. For example declaring Bar's constructor explicit as - explicit Bar(int i); - would prevent us from calling ProcessBar as - ProcessBar(10); .
implicit conversion in the companion object of the source or expected target types don't need to be imported.
True enough. Now, the method camelize
is defined on the class MyString
, and, indeed, there is an implicit conversion to MyString
inside its object companion. However, there is nothing in the code telling the compiler that MyString
is the expected target type.
If, instead, you wrote this:
val x = ("active_record": MyString).camelize
then it would work, because the compiler would know you expect "active_record"
to be a MyString
, making it look up the implicit conversion inside object MyString
.
This might look a bit restrictive, but it actually works in a number of places. Say, for instance, you had:
class Fraction(num: Int, denom: Int) {
...
def +(b: Fraction) = ...
...
}
And then you had a code like this:
val x: Fraction = ...
val y = x + 5
Now, x
does have a +
method, whose expected type is Fraction
. So the compiler would look, here, for an implicit conversion from Int
to Fraction
inside the object Fraction
(and inside the object Int
, if there was one, since that's the source type).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With