Scala - 可选参数,无需用户输入 Some(...)

Scala - Optional Arguments without requiring user to input Some(...)

我正在设计一个程序。我是 Scala 的新手,但似乎使用以下方法处理可选参数:

def f1(my_string: Option[String] = None) = {

// Maybe do some pattern matching here to extract the value

}

但是,对于最终用户而言,这非常难看,因为他们需要像这样调用此函数:

f1(Some("foo")

是否有技术或模式可以将其变成:

f1("foo"))

并且仍然使用可选参数?即 f1() 也有效?

我问的原因是我显然使用过 Scala 库,其中没有必要添加显式 Some(..),但在它们的源代码中它们定义了上述函数。我个人会使用默认参数,但不知道为什么这是一种设计模式。

您可以重载该方法,而不是 Option

f1() :ReturnType = {...}

f1(arg:String) :ReturnType = {...}

Option 在诸如

的调用中的句法成本
f1(Some("foo"))

与大型代码库中空指针异常风险最小化的价值相比是微不足道的。霍尔,图灵奖获得者,appologised

I call it my billion-dollar mistake. It was the invention of the null reference in 1965.

一个选项是为此类参数创建一个助手 class 以避免链接线程中的 anyToOption 隐式转换:

class OptArg[A](val asOption: Option[A])

object OptArg {
  def NoArg[A] = new OptArg[A](None)
  implicit def fromValue[A](x: A): OptArg[A] = new OptArg(Some(x))
  // optional
  implicit def toOption[A](arg: OptArg[A]) = arg.asOption
}

// use
def f1(my_string: OptArg[String] = NoArg) = {
  // can use my_string as if it was Option,
  // or call my_string.asOption explicitly
}

在简单的情况下当然重载会更合适,但如果你有很多可选参数则不适合。

缺点是依赖于隐式转换,但我认为这是非常良性的,不太可能意外触发。

OTOH 我认为在实践中很少见参数是可选的,但 "no argument" 不对应于该类型的 some 默认值,所以我会看能不能定义成

def f1(my_string: String = something)

避免整个问题。