2017-05-08 26 views
2

说我有一个本地方法/功能地图实例使用功能斯卡拉

def withExclamation(string: String) = string + "!" 

有Scala中的一个方式,通过提供这种方法来转换实例?假设我想为一个字符串附加一个感叹号。就像:

val greeting = "Hello" 
val loudGreeting = greeting.applyFunction(withExclamation) //result: "Hello!" 

我想在实例上编写链式转换时能够调用(本地)函数。

编辑:多个答案显示如何编程这种可能性,所以似乎这个功能是不存在的仲裁类。对我来说,这个功能似乎非常强大。考虑在Java中我想对字符串执行多个操作的位置:

appendExclamationMark(" Hello! ".trim().toUpperCase()); //"HELLO!" 

操作的顺序与它们的读取方式不一样。最后的操作,appendExclamationMark是第一个出现的单词。目前,在Java中我有时会做的事:

Function.<String>identity() 
    .andThen(String::trim) 
    .andThen(String::toUpperCase) 
    .andThen(this::appendExclamationMark) 
    .apply(" Hello "); //"HELLO!" 

读取在一个实例表达操作链方面更好,而且还含有大量的噪音,这是不直观拥有在字符串实例最后一行。我希望这样写:

" Hello " 
    .applyFunction(String::trim) 
    .applyFunction(String::toUpperCase) 
    .applyFunction(this::withExclamation); //"HELLO!" 

显然applyFunction函数的名称可以是任何东西(短请)。我认为向后兼容性是Java的Object没有这个的唯一原因。 有没有任何技术上的原因,为什么这不被添加,比如Any或AnyRef类?

+0

什么是'someInstance'?你会期望'变革'做什么?调用'toString'? –

+0

修正:someInstance应该被命名为greeting –

回答

5

您可以用implicit class它提供了一种用自己的方法扩展现有类型做到这一点:

object StringOps { 
    implicit class RichString(val s: String) extends AnyVal { 
    def withExclamation: String = s"$s!" 
    } 

    def main(args: Array[String]): Unit = { 
    val m = "hello" 
    println(m.withExclamation) 
    } 
} 

产量:

hello! 
1

如果你想申请任何功能(匿名,从方法转换等),您可以使用Yuval Itzchakov的答案的变体:

object Combinators { 
    implicit class Combinators[A](val x: A) { 
    def applyFunction[B](f: A => B) = f(x) 
    } 
}