问题 在scala中设置函数参数的默认值


我试图在scala中为匿名函数设置默认值,因此无法找到任何解决方案。希望有人能帮助我。

我有以下结构,

case class A(id:Int = 0)

case class B(a:A)

object B {
     def func1(f:Int = 0)={
      ........
     }
 def func2(f:A => B = (how to give default value ?))={
        case Nothing => {
         //do something....
        }
        case _ => {
         //do some other thing......
        }
 }
} 

基本上,我想将参数作为可选参数传递。我怎样才能做到这一点?


4026
2017-09-30 08:53


起源



答案:


像任何其他默认参数一样:

scala> def test(f: Int => Int = _ + 1) = f
test: (f: Int => Int)Int => Int

scala> test()(1)
res3: Int = 2

或者使用String:

scala> def test(f: String => String = identity) = f
test: (f: String => String)String => String

scala> test()
res1: String => String = <function1>

scala> test()("Hello")
res2: String = Hello

编辑:

如果您想使用默认提供的功能,则必须使用 () 显式地,Scala不会粘贴默认参数。

如果您不想使用默认功能并提供明确功能,请自行提供:

scala> test(_.toUpperCase)("Hello")
res2: String = HELLO

14
2017-09-30 09:04



我想知道这个答案是如何与这个问题相关的,它似乎是关于使用curried函数而不是默认参数? - Gyro Gearless
@GyroGearless不,你错了 - 4lex1v
好的,我知道了。但我想如果它有一个非默认情况的例子,例如你的例子会更有启发性。 test(_*33)(1) - Gyro Gearless
@GyroGearless谢谢,再补充一个例子来说明一点 - 4lex1v


答案:


像任何其他默认参数一样:

scala> def test(f: Int => Int = _ + 1) = f
test: (f: Int => Int)Int => Int

scala> test()(1)
res3: Int = 2

或者使用String:

scala> def test(f: String => String = identity) = f
test: (f: String => String)String => String

scala> test()
res1: String => String = <function1>

scala> test()("Hello")
res2: String = Hello

编辑:

如果您想使用默认提供的功能,则必须使用 () 显式地,Scala不会粘贴默认参数。

如果您不想使用默认功能并提供明确功能,请自行提供:

scala> test(_.toUpperCase)("Hello")
res2: String = HELLO

14
2017-09-30 09:04



我想知道这个答案是如何与这个问题相关的,它似乎是关于使用curried函数而不是默认参数? - Gyro Gearless
@GyroGearless不,你错了 - 4lex1v
好的,我知道了。但我想如果它有一个非默认情况的例子,例如你的例子会更有启发性。 test(_*33)(1) - Gyro Gearless
@GyroGearless谢谢,再补充一个例子来说明一点 - 4lex1v


使用隐式参数。在参数中放置参数的隐式值。除非您提供显式参数或在调用范围中提供了另一个隐式值,否则将使用此方法。

case class A(id:Int = 0)

case class B(a:A)

object B {
  implicit val defFunc: A => B = {a: A =>  new B(a) }
  def func1(f:Int = 0)={
  }
  def func2(implicit func: A => B) = { ... }
} 

这种方法与Alexlv方法的区别在于

  1. 这适用于独立函数和方法。
  2. 范围规则允许在适当的范围内提供适当的覆盖。 Alex的方法需要子类化或eta-expansion(使用部分应用程序)来更改默认值。

我提供此解决方案,因为您已经在使用对象。否则,Alexvlv的例子就更简单了。


1
2017-09-30 11:37



从它的用法来看,你的func2方法非常笨拙。你拿两个参数列表并返回一个部分函数,​​所以如果你尝试调用结果函数,这将不是你所期望的,即调用 func2(10) (第二个分支全部匹配 _)会抛出错误原因 func2 期待一个隐含的参数,你给它一个int。我可以从生产中给你大量的例子,当隐含(设计接近你的设计)是一场灾难并且打破了很多。 - 4lex1v
真正。试图将原始代码保留原样,让自己受到阻碍。编辑为理智。 - itsbruce