有条件地将两个函数之一应用于一个参数

时间:2014-08-12 02:00:10

标签: scala

我有两个带有一个参数的函数,String。我是基于某些condition应用其中一个或另一个。这就是我的尝试:

def foo(s: String) = { ... }
def bar(s: String) = { ... }
(if (condition) foo else bar)("baz")

但我收到这样的错误:

<console>:10: error: missing arguments for method foo;
follow this method with `_' if you want to treat it as a partially applied function
              (if (true) foo else bar)("baz")
                         ^

我尝试写foo_,但当然我得到error: not found: value foo_。在Scala中表达这个成语的正确方法是什么?

4 个答案:

答案 0 :(得分:6)

方法名称和下划线之间需要一个空格。这很好用:

def foo(s: String) = s + "-FOO"
def bar(s: String) = s + "-BAR"
val condition = true
(if (condition) foo _ else bar _)("baz")
// res0: String = baz-FOO

方法名称后面的下划线告诉Scala您希望将该方法作为更高级别的函数传递。根据我的理解,这是一种消除模式是否要将方法作为函数传递或传递没有参数的方法的结果的方法。例如:

def f = 1
val x = Some(f)

x的类型应该是什么?会是Some[Int]还是Some[()=>Int]?它应该默认为前者,但如果你想要后者,你可以使用下划线表示法:

val y = Some(f _)

你必须处理所有这些下划线的废话,因为Scala methods aren't functions。如果您将foobar声明为函数而不是方法,则原始代码按原样运行:

val foo = (s: String) => s + "-FOO"
val bar = (s: String) => s + "-BAR"
val condition = false
(if (condition) foo else bar)("baz")
// res1: String = baz-BAR

答案 1 :(得分:1)

我想提几件事:

def foo(s:String)= {...} def bar(s:String)= {...}

foo和bar不是函数,只有普通的方法。此外,def f = 3也是方法而非功能

(if(condition)foo else bar)(“baz”)显然,由于(“baz”)参数,此语句需要foo和bar为函数

正如@wendao所提到的那样使用_来改变方法的功能。我认为最简单的解决方案是将foo和bar定义为函数。

def foo: String => String = { value => 
  "Hi " + value
}

def bar: String => String = { value =>
  "farewell " + value
}

val x: Some[String => String] = Some(foo)

(if (true) foo else bar)("John")    // Hi John

答案 2 :(得分:0)

它不知道你实际想要返回一个函数,你必须告诉它你想要的是一个名字参数:

  def foo(x : String) = x                         //> foo: (x: String)String
  def bar(x : String) = x                         //> bar: (x: String)String
  val condition = true                            //> condition  : Boolean = true

  val result : String => String = if (condition) foo else bar
                                                  //> result  : String => String = <function1>
  result("something")                             //> res0: String = something

答案 3 :(得分:0)

这有点荒谬:

scala> var b = true
b: Boolean = true

scala> def f(s: String) = s"f+$s"
f: (s: String)String

scala> def g(s: String) = s"g+$s"
g: (s: String)String

scala> import Function._ ; import PartialFunction._
import Function._
import PartialFunction._

scala> unlift(condOpt(_: String) { case s if b => f(s) }) applyOrElse ("hi", g)
res0: String = f+hi

scala> b = false
b: Boolean = false

scala> unlift(condOpt(_: String) { case s if b => f(s) }) applyOrElse ("hi", g)
res1: String = g+hi