关于缩写地图的困惑

时间:2015-02-23 12:05:21

标签: scala

我会想到以下代码:

val a = Array(1, 2, 3, 4, 5)
println(a.map(n => "x"))

可以缩写为:

val a = Array(1, 2, 3, 4, 5)
println(a.map("x"))

但后者给了我以下例外。这是为什么?

  

java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:   1 java.lang.StringIndexOutOfBoundsException:字符串索引   范围:1在java.lang.String.charAt(String.java:658)at   scala.collection.immutable.StringLike $ class.apply(StringLike.scala:52)     在   scala.collection.immutable.WrappedString.apply(WrappedString.scala:33)     在   scala.collection.immutable.WrappedString.apply(WrappedString.scala:33)     在   scala.collection.TraversableLike $$ anonfun $表$ 1.适用(TraversableLike.scala:245)     在   scala.collection.TraversableLike $$ anonfun $表$ 1.适用(TraversableLike.scala:245)     在   scala.collection.IndexedSeqOptimized $ class.foreach(IndexedSeqOptimized.scala:33)     在   scala.collection.mutable.ArrayOps $ ofInt.foreach(ArrayOps.scala:234)     在   scala.collection.TraversableLike $ class.map(TraversableLike.scala:245)     在scala.collection.mutable.ArrayOps $ ofInt.map(ArrayOps.scala:234)

2 个答案:

答案 0 :(得分:7)

Strings也是函数Int => Char,它将给定索引处的char提取到字符串中。因此

a.map("x")

相当于

a.map(i => "x".charAt(i))

a的第一个元素是1所以这将尝试在字符串x中的索引1处找到超出范围的char,因此是例外。

如果您想要一个始终返回"x"的函数,那么您可以使用Function.const

import Function.const
a.map(const("x"))

答案 1 :(得分:3)

在scala中,String只是java.lang.Strings的占位符类型。

String的所有实例都隐式转换为scala.collection.immutable.StringOps,扩展了特征StringLike[ String ],后者又扩展了特征IndexedSeqOptimized[Char, String]

现在,trait IndexedSeqOptimized[Char, String]定义了一个抽象的应用方法apply(index: Int): Char,它由特征StringLike[ String ]实现。

因此,像val s = "A String"这样的每个String实例都可以用作类型为Int => Char的函数 - val c = s( 0 )

现在,您的a.map( "x" )相当于a.map( i => "x".apply( i ) )a.map( "x".apply( _ ) )a.map( i => ( "x" )( i ) )或仅a.map( "x".apply )