scala> val names = List("Peter", "Paul", "Mary")
names: List[String] = List(Peter, Paul, Mary)
scala> names.map(_.toUpperCase)
res12: List[String] = List(PETER, PAUL, MARY)
在这种情况下,下划线表示唯一的输入参数,即名称元素。此字符串被隐式转换为 StringOps,并调用 toUpperSame。
但是,这不起作用:
scala> names.map(StringOps.toUpperCase _)
<console>:14: error: value toUpperCase is not a member of object scala.collection.immutable.StringOps
names.map(StringOps.toUpperCase _)
我认为这种语法是我从 toUpperCase 方法获取对函数的引用的方式。
首先_.toUppercase
没有将String
转换为StringOps
的隐式转换,由于toUppercase
属于String
类型,因此没有必要转换为StringOps
。
所以对于_.toUppercase
实际上是扩展到高阶函数:val a: String => String = (str: String) => str.toUpperCase
.
StringOps
Predef.scala
中定义的隐式转换:augmentString
,并且这种转换只会在StringOps
的方法中使用时才会发生,例如:slice
、stripSuffix
、stripPrefix
等,例如:
"name".slice(0, 2) // convert "name" to new StringOps("name").slice(0,2)
"name".stringPrefix
StringOps 是一个类,因此要使用它的方法,您需要实例化一个实例:
names.map( x => (new StringOps(x)).toUpperCase )
或
names.map( new StringOps(_) toUpperCase )
StringOps 是 String 类的包装类,这意味着它使用其他方法(如您正在使用的方法)"丰富"了此类。
当您想在字符串实例上调用方法时,只需执行以下操作:
instanceName.methodName
这正是您在第一个示例中所做的。
但是,在第二个示例中,您将执行以下操作:
methodName(instanceName)
toUpperLetter不接受参数,它是在字符串本身的实例上调用的。