为什么在这种情况下scala的(1 to 1000).foreach会抛出异常?

7
在repl中,这会抛出一个异常,我不知道为什么。 我真的很想理解这个。
scala> (1 until 10000).foreach("%s%s".format("asdf", "sdff"))
java.lang.StringIndexOutOfBoundsException: String index out of range: 8
    at java.lang.String.charAt(String.java:686)
    at scala.collection.immutable.StringLike$class.apply(StringLike.scala:54)
    at scala.collection.immutable.WrappedString.apply(WrappedString.scala:32)
    at scala.collection.immutable.WrappedString.apply(WrappedString.scala:32)
    at scala.collection.immutable.Range.foreach(Range.scala:75)

你正在尝试执行的是(1 until 10000).foreach(_ => "%s%s".format("asdf", "sdff")) - sourcedelica
2个回答

12

请将下面的代码视为未包装的伪代码:

val str = "%s%s".format("asdf", "sdff")
// "asdfsdff" you see, only 8 characters
(1 until 10000).foreach(x => str.getCharAt(x))

1
实际上,调用的是 str.apply 而不是 str.getCharAt - kiritsuku

7

Scala中的字符串(Strings)可以像从索引到给定索引处的字符一样用作函数:

val s: Int => Char = "abcd"
val c: Char = s(1)

这是Scala中的一种通用机制,其中具有apply方法的对象可以被视为函数。字符串的apply方法在StringOps中定义。将字符串"asdfsdff"传递给foreach,范围内的每个连续值都传递给函数。当索引达到8时,由于超出了范围,因此会抛出异常。

需要明确的是,您不能将任何具有apply方法的对象视为函数。必须存在一个隐式转换函数才能在此类情况下使用它。在这里,它是在Predef上的implicit def wrapString(s: String): WrappedString,因为WrappedString继承自PartialFunction[Int, Char] - Luigi Plinge
Om-nom-nom先回答了,所以我会给他点数。感谢您的回答-我已经点赞了。 - JasonG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接