【问题标题】:Scala - Optional Arguments without requiring user to input Some(...)Scala - 不需要用户输入 Some(...) 的可选参数
【发布时间】:2020-10-02 16:01:38
【问题描述】:

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

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

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

}

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

f1(Some("foo")

有没有一种技术或模式可以把它变成:

f1("foo"))

仍然可以使用可选参数吗?即 f1() 也可以使用?

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

【问题讨论】:

  • 查看我的回答 here 以及所有线程。
  • 谢谢,这正是我想要的

标签: scala error-handling functional-programming pattern-matching options


【解决方案1】:

一种选择是仅为此类参数创建一个帮助器类,以避免链接线程中的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 我认为在实践中很少有参数是可选的但“无参数”不对应于该类型的 some 默认值,所以我会看看它是否可以定义作为

def f1(my_string: String = something)

避免整个问题。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 谢谢@jwvh,作为一个有趣的问题,如果我正在使用一个类,那么惯用的方式仍然会重载构造函数吗?
    • 在这种情况下,您可能想要使用辅助构造函数。他们有some restrictions,但很有用。
    【解决方案3】:

    Option 在调用中的语法成本,例如

    f1(Some("foo"))
    

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

    我称之为我的十亿美元错误。这是 null 的发明 参考 1965 年。

    【讨论】:

    • 但为什么要把它和那个风险比较呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 2019-06-19
    • 2019-03-04
    • 1970-01-01
    相关资源
    最近更新 更多