我会想到以下代码:
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)
答案 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 )
。