【问题标题】:Scala String toInt - Int does not take parametersScala String toInt - Int 不带参数
【发布时间】:2017-02-18 20:34:32
【问题描述】:

所以我在学习 Scala 时遇到了这个棘手的问题......

如果我们有一个String 并想将其转换为Int,我在网上找到的所有示例都说:“太简单了!只需使用String.toInt!”

好的:

var x = readLine().toInt

足够简单。我假设toIntString 的函数。但如果是这样的话,我应该可以用括号调用toInt,对吧?来自 Java,这对我来说感觉更自然:

var x = readLine().toInt()

但是,唉! Scala 给了我以下错误:

[错误] /home/myhome/code/whatever/hello.scala:13: Int 不接受 参数

[错误] var x = readLine().toInt()

好奇。这个错误是什么意思? toInt 不是String 的函数吗?同样,为什么我可以同时做:

var x = readLine().toLowerCase()
var y = readLine().toLowerCase

没有任何问题?

编辑:重复的问题没有解决 toLowerCasetoInt 的问题。

【问题讨论】:

标签: string scala integer


【解决方案1】:

这是一个很好的问题,我不认为它与question about defining zero-arity methods 有或没有括号的重复。

这里toInttoLowerCase的区别在于toInt是标准库的StringOps类提供的句法扩充。您可以通过在 REPL 中使用 reifyshowCode 来检查:

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

这只是对丰富方法调用进行脱糖,并向您展示应用了哪些隐式转换来支持它。

如果我们查看toInt method on StringOps,我们会看到它的定义没有括号。正如对可能重复问题的答案所指出的那样,如果 Scala 中的零参数方法在没有括号的情况下定义,则不能用括号调用它(尽管如果它用括号定义,则可以以任何一种方式调用)。

这就是"1".toInt() 不起作用的原因。如果String 是遵循普通Scala 命名约定的普通Scala 类,那么"ABC".toLowerCase() 也不起作用,因为该方法将在没有括号的情况下定义,因为它没有副作用(这只是一个约定,但它往往在 Scala 代码中非常一致地应用)。

问题在于String 实际上并不是Scala 标准库中的一个类——它只是java.lang.String。在 JVM 级别,用括号定义的零参数方法和不带括号定义的方法之间没有区别——这纯粹是 Scala 的区别,它没有编码在 JVM 方法签名中,而是存储在存储在类文件。

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

【讨论】:

  • 感谢您的回答。因此,为了弥合我的理解差距,零参数方法是一种没有括号定义的方法,这些方法只是按照惯例(即,我可以定义一个不带括号的参数的方法,使其更像 Java)?所以我会调用一个零参数方法,就好像我正在访问一个字段一样?如果我使用 Java 类/库,就没有零元方法之类的东西吗?另外,什么是“副作用”方法?
  • @KennethWorden 我使用“零参数”来指代任何不带参数的方法,无论它是带括号还是不带括号定义的。 Java 有不带参数的方法(在这个意义上算作零参数),但它并没有区分它们是否用括号定义(就 Java 语法而言,它们都是)。
  • 这里的“副作用”意味着它不是数学意义上的函数——它可能会打印一些东西,在后续调用中返回不同的值,等等。
  • 我会稍微扩展一下 Travis 是如何解释“副作用”的,因为它非常重要,而且对于具有 Java 背景的人来说,它可能并不那么明显。如果函数正在执行一些以任何方式影响函数体之外的“世界状态”的动作,那么函数就是副作用。这并不意味着它必须改变一些值;它的效果是可观察的就足够了(例如,如 Travis 所说,打印到控制台)。这是不好的。函数的另一个坏事是保持一些可变状态,这可能导致相同的输入参数返回不同的结果。
  • 如果一个函数没有副作用,只依赖于它的参数并且对于相同的参数总是返回相同的结果,我们称这样的函数为“纯”。使用零参数函数,我们失去了仅依赖于其参数的条件,并且对于相同的参数总是返回相同的结果(因为没有参数),所以我们可能“搞砸”的只是产生副作用。如果我们没有(没有打印、没有日志记录、没有任何请求、没有数据库写入等),那么它就是一个安全、幂等的函数——如果你愿意的话,它是一个简单的 getter——并且按照惯例应该没有括号。
猜你喜欢
  • 1970-01-01
  • 2018-02-28
  • 2017-05-03
  • 2020-08-12
  • 2016-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-03
相关资源
最近更新 更多