【问题标题】:Default empty case for varargs可变参数的默认空大小写
【发布时间】:2016-05-15 23:37:56
【问题描述】:

假设您希望在调用带有可变参数的方法时使用模式匹配,如下所示:

def foo(bar: Int*) = ???

val x = false
foo(x match {
  case true => 1
  case _ =>
})

运行上述代码会导致类型不匹配错误,因为foo 需要Int 类型的参数,但在默认情况下找到Unit。另一方面,删除默认大小写会导致警告说匹配可能并不详尽,这是正确的。

我的问题是,我如何为匹配提供一个 empty 默认情况(这会导致在没有任何参数的情况下调用 foo())?

【问题讨论】:

  • 如果你只传递一个Int,为什么要使用可变参数?
  • @YuvalItzchakov 给出的例子是一个MWE,实际用例更复杂
  • 如果这个 MWE 不是您真正的问题,我们可能无法提供最佳解决方案,因为我们只看到实际问题的“近亲”。
  • @YuvalItzchakov 没有过多的细节,我有一个接受可变参数的方法。我需要以三种不同的方式调用此方法:不带任何参数、带一个参数或带多个参数。为了决定使用哪个参数调用我的方法,我对一个具有 20 多种不同可能值的变量进行模式匹配,但我只对其中的几个真正感兴趣。在所有其他情况下,我希望在没有任何参数的情况下调用我的方法。希望这可以澄清事情。

标签: scala pattern-matching variadic-functions


【解决方案1】:

您可以按顺序捕获匹配结果,并将缺少参数表示为空参数。然后将结果放入参数中:

val x = true
foo((x match {
  case true => Seq(1)
  case _ => Seq.empty
}):_*)

【讨论】:

  • val args = x match ...; foo(args: _*) 可能更具可读性。
  • 当然是。如果它像 OP 评论所暗示的那样复杂(20 多个值),它甚至可能需要自己的方法来保持清洁。但显然我们没有看到全貌。
【解决方案2】:

一种选择是使用Option[Int] 而不是Int

def foo(bar: Option[Int]*) = ???

val x = false
foo(x match {
  case true => Some(1)
  case _ => None
})

我认为if-else 表达式在这里会不那么冗长:

foo(if (x) Some(1) else None)

但我认为,如果您匹配单个 Boolean,则根本没有传递可变参数的意义。

【讨论】:

    猜你喜欢
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 2016-03-12
    • 2021-10-11
    • 2021-08-18
    • 2011-05-07
    • 2014-05-31
    相关资源
    最近更新 更多