So I'm learning Scala and I came across this finicky issue...
If we have a String
and want to convert it to an Int
, all examples that I've found online say, "It's so simple! Just use String.toInt
!"
Okay:
var x = readLine().toInt
Simple enough. I'm assuming toInt
is a function of String
. But if that's the case, I should be able to call toInt
with parentheses, right? Coming from Java, this feels more natural to me:
var x = readLine().toInt()
But alas! Scala gives me the following error:
[error] /home/myhome/code/whatever/hello.scala:13: Int does not take parameters
[error] var x = readLine().toInt()
Curious. What does this error mean? Is toInt
not a function of String
? Similarly, why can I do both:
var x = readLine().toLowerCase()
var y = readLine().toLowerCase
with out any problems?
Edit: The duplicate question does not address the toLowerCase
vs toInt
issue.
A string can be converted to integer in Scala using the toInt method. This will return the integer conversion of the string. If the string does not contain an integer it will throw an exception with will be NumberFormatException. So, the statement: val i = "Hello".
Scala Char toInt() method with example The toInt() method is utilized to convert a stated character into an integer or its ASCII value of type Int. Return Type: It returns Integer or ASCII value of the corresponding character of type Int.
This is a good question, and I don't think it counts as a duplicate of the question about defining zero-arity methods with or without parentheses.
The difference between toInt
and toLowerCase
here is that toInt
is a syntactic enrichment provided by the standard library's StringOps
class. You can check this by using reify
and showCode
in the REPL:
scala> import scala.reflect.runtime.universe.{ reify, showCode }
import scala.reflect.runtime.universe.{reify, showCode}
scala> showCode(reify("1".toInt).tree)
res0: String = Predef.augmentString("1").toInt
This just desugars the enrichment method call and shows you what implicit conversion has been applied to support it.
If we look at the toInt
method on StringOps
, we see that it's defined without parentheses. As the answer to the possible duplicate question points out, if a zero-arity method in Scala is defined without parentheses, it can't be called with parentheses (although if it's defined with parentheses it can be called either way).
So that's why "1".toInt()
doesn't work. If String
were a normal Scala class following normal Scala naming conventions, "ABC".toLowerCase()
wouldn't work either, since the method would be defined without parentheses, since it's not side-effecting (this is just a convention, but it tends to be pretty consistently applied in Scala code).
The problem is that String
isn't actually a class in the Scala standard library—it's just java.lang.String
. At the JVM level, there's no difference between a zero-arity method defined with parentheses and one defined without parentheses—this is purely a Scala distinction, and it's not encoded in the JVM method signature, but in a separate batch of metadata stored in the class file.
The Scala language designers decided to treat all zero-arity methods that aren't defined in Scala (and therefore don't have this extra metadata) as if they were defined with parentheses. Since the toLowerCase
method on String
is really and truly a method of the java.lang.String
class (not a syntactic enrichment method like toInt
), it falls into this category, which means you can call it either way.
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