Scala 两个函数之一对一个参数的条件应用

Scala 两个函数之一对一个参数的条件应用,scala,Scala,我有两个函数接受一个参数,一个字符串。我将根据一些条件应用其中一个。这就是我所尝试的: 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

我有两个函数接受一个参数,一个
字符串
。我将根据一些
条件应用其中一个。这就是我所尝试的:

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")
                         ^
:10:错误:方法foo缺少参数;
如果要将其视为部分应用的函数,请使用“\u1”遵循此方法
(如果为(真)foo else bar)(“baz”)
^

我试着写
foo\uuz
,但当然我得到了
错误:找不到:value foo\uz
。用Scala来表达这个习惯用法的正确方法是什么?

它不知道您真正想要返回的是一个函数,您必须告诉它您想要的是一个按名称的参数:

  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
def foo(x:String)=x/>foo:(x:String)String
定义条(x:String)=x/>bar:(x:String)字符串
val条件=真//>条件:布尔值=真
val结果:String=>String=if(条件)foo-else条
//>结果:String=>String=
result(“something”)/>res0:String=something

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

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 _)

你必须处理所有这些废话,因为。如果将
foo
bar
声明为函数而不是方法,则原始代码的工作方式如下:

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

这有点荒谬:

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

有几件事我想提一下:

def foo(s:String)={…} 定义栏(s:String)={…}

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

(如果(条件)foo else bar)(“baz”)显然,由于(“baz”)参数,该语句需要foo和bar成为函数

正如@wendao提到的,使用u将方法更改为函数。我认为最简单的解决方案是将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

foo
没有跟随
foo
它正在尝试调用方法
foo
。对于来自其他语言的人来说,这可能看起来很奇怪,因为在方法名称中不允许使用
\uu
。@samthebest是的,我知道
\u
在方法名称中是允许的,所以我觉得很奇怪。我猜看到我本应该写
foo\uu
让我意识到我只是误解了错误告诉我要做的事情。def f=1是一个方法而不是函数:)哦,对了,我误解了错误消息。我记得在我读的一本关于Scala的书中,
\uu
是一种“占位符”,所以这对我来说现在有点意义。除了类主体之外的
def
仍然在声明一个方法而不是一个函数,这让我很反感。@2rs2ts-你说的“类主体之外”是什么意思?你是说你在Scala解释器(REPL)中执行
def
?如果是这样,您应该知道在REPL中键入的所有内容都隐式地包装在对象定义中。实际上,您可以在REPL中键入
this
,以获取对该封闭对象的引用。在REPL中或在没有
类的文件中
/
对象
声明,是的。因此,如果在前者中,它被封装在隐式的
对象定义中,那么我假设没有
类的文件也是如此,没有
/
对象
声明?@2rs2ts-我实际上从未编写过这样的Scala“脚本”(我有点忘记了存在这样的功能)。但是,我认为这是一个安全的假设,因为JVM不允许类定义之外存在任何东西。为了确认,试着把
println(this)
放在你的文件中,看看会发生什么。这对我来说不是很直观(我来自Python),但我会咬一口。如果它是一个方法,它属于哪个类?如果它是一个方法,它不属于任何类型,它只是有一个返回类型。但是,函数将属于特征函数0、函数1、函数2、函数3等。对于这种情况,def(x:String):String=“123”(f).isInstanceOf[Function0[]]//false(f).isInstanceOf[Function1[,]]//true。在Scala中,函数是对象,我总是认为方法是函数的特殊形式。例如,若您有接受函数的参数,它实际上可以使用方法。def add3(x:Int)=x+3列表(1,2,3).map(add3)。map接受函数而不是方法。所以在Scala中,可能存在根本不属于类的方法?我认为您应该阅读此
((if(true)f else g):(String=>String))(“hi”)
适用于方法f,g。另外,
val f=(s:String)=>s“hi,$s”
val f:String=>String=“hi”+
。那么
result
是包含函数的
val
吗?