Predef.readLine 行为

发布于 2024-12-08 21:32:15 字数 291 浏览 0 评论 0原文

scala> val input = readLine("hello %s%n", "world")
hello WrappedArray(world)
input: String = ""

scala> val input = Console.readLine("hello %s%n", "world")
hello world
input: String = ""

这里造成差异的原因是什么? (我也尝试编译它,所以它不是 REPL 的东西。)

Scala 版本 2.9.0-1

scala> val input = readLine("hello %s%n", "world")
hello WrappedArray(world)
input: String = ""

scala> val input = Console.readLine("hello %s%n", "world")
hello world
input: String = ""

What's the reason for the difference here? (I tried it compiled as well, so it's not a REPL thing.)

Scala version 2.9.0-1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独自唱情﹋歌 2024-12-15 21:32:15

这似乎是 Predef 中的一个错误:

def readLine(text: String, args: Any*) = Console.readLine(text, args)

当我认为应该是:

def readLine(text: String, args: Any*) = Console.readLine(text, args: _*)

您使用的第一个版本正在调用 Prefef.readLine。由于缺少 _* 类型描述,因此使用 args 作为 的重复参数 args 的单个第一个参数来调用该函数Console.readLine

uncurry 编译阶段,这个单个参数被包装到 WrappedArray 中,以便可以将其视为 Seq[Any]。然后使用 toString 方法转换 WrappedArray,这就是 "hello %s%n" 中的 %s 使用的方法。我认为这就是发生的事情。

在第二个版本中,args 从一开始就被视为 Seq[Any],并且不会发生任何转换。

整个事情有点有趣,因为一般来说编译器不会让你这样做:

scala> def f(s: Int*) = s foreach println
f: (s: Int*)Unit

scala> def g(s: Int*) = f(s)
<console>:8: error: type mismatch;
 found   : Int*
 required: Int
       def g(s: Int*) = f(s)

使用Any,你就过了打字阶段。

It seems like a bug in Predef:

def readLine(text: String, args: Any*) = Console.readLine(text, args)

When I think it should be:

def readLine(text: String, args: Any*) = Console.readLine(text, args: _*)

The first version you use is calling Prefef.readLine. Because of the missing _* type ascription, the function is called with args as the single first argument of the repeated argument args of Console.readLine.

In the uncurry compilation phase, this single argument is wrapped into a WrappedArray so that it it can be treated as a Seq[Any]. The WrappedArray is then converted using the toString method and this is what is used for %s in "hello %s%n". I think that is what happens.

In the second version args is treated from the start as a Seq[Any] and no conversion happens.

The whole thing is a bit funny, because in general the compiler does not let you do this:

scala> def f(s: Int*) = s foreach println
f: (s: Int*)Unit

scala> def g(s: Int*) = f(s)
<console>:8: error: type mismatch;
 found   : Int*
 required: Int
       def g(s: Int*) = f(s)

With Any, you get past the typer phase.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文