简体   繁体   English

Scala String toInt - Int不接受参数

[英]Scala String toInt - Int does not take parameters

So I'm learning Scala and I came across this finicky issue... 所以我正在学习Scala,我遇到了这个挑剔的问题......

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 !" 如果我们有一个String并希望将它转换为Int ,那么我在网上找到的所有例子都说:“它太简单了!只需使用String.toInt !”

Okay: 好的:

var x = readLine().toInt

Simple enough. 很简单。 I'm assuming toInt is a function of String . 我假设toIntString的函数。 But if that's the case, I should be able to call toInt with parentheses, right? 但如果是这样的话,我应该可以用括号来调用toInt ,对吧? Coming from Java, this feels more natural to me: 来自Java,这对我来说更自然:

var x = readLine().toInt()

But alas! 可惜! Scala gives me the following error: Scala给了我以下错误:

[error] /home/myhome/code/whatever/hello.scala:13: Int does not take parameters [错误] /home/myhome/code/whatever/hello.scala:13:Int不带参数

[error] var x = readLine().toInt() [error] var x = readLine()。toInt()

Curious. 好奇。 What does this error mean? 这个错误是什么意思? Is toInt not a function of String ? toInt不是函数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. 编辑:重复的问题没有解决toLowerCasetoInt问题。

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. 之间的区别toInttoLowerCase这里是toInt是由标准库提供了一个语法富集StringOps类。 You can check this by using reify and showCode in the REPL: 您可以通过检查这个reifyshowCode在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. 如果我们StringOps查看toInt方法 ,我们会看到它的定义没有括号。 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). 正如可能重复问题的答案所指出的那样,如果Scala中的零arity方法定义为没有括号,则不能用括号调用它(尽管如果它用括号定义,它可以以任一方式调用)。

So that's why "1".toInt() doesn't work. 这就是为什么"1".toInt()不起作用的原因。 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). 如果String是遵循正常Scala命名约定的普通Scala类,则"ABC".toLowerCase()也不起作用,因为该方法将被定义为没有括号,因为它不是副作用(这只是一个约定,但它往往在Scala代码中一致地应用)。

The problem is that String isn't actually a class in the Scala standard library—it's just java.lang.String . 问题是String实际上不是Scala标准库中的一个类 - 它只是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. 在JVM级别,使用括号定义的零arity方法和没有括号定义的零方法之间没有区别 - 这纯粹是Scala的区别,并且它不是在JVM方法签名中编码,而是在存储在其中的单独的一批元数据中编码。类文件。

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. Scala语言设计者决定将所有未在Scala中定义的零方法(因此没有这些额外的元数据)视为用括号定义。 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. 由于String上的toLowerCase方法确实是java.lang.String类的方法(不是像toInt这样的语法丰富方法),所以它属于这一类,这意味着你可以调用它。

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

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