【问题标题】:Scala pattern matching for tuple with options still needs unwrapping for the some case在某些情况下,带有选项的元组的 Scala 模式匹配仍然需要展开
【发布时间】:2019-09-27 02:23:07
【问题描述】:

f(Int) 是一个返回 Option[Int] 的函数。

def findIntPair(x: Int, y: Int): (Int, Int) = {
    (f(x), f(y)) match {
      case (None, None) || (None, _) || (_, None)  => fail("Unable to find the pair" )
      case (a, b) => (a.get, b.get) // why I still need to unwrap by get
    } 
}

为什么最后一个 case(a, b) 没有将它们解包到 Int 中,但仍将它们保留为 Option[Int]

仅供参考:我正在使用 intelliJ IDEA。

【问题讨论】:

  • f的定义在哪里?
  • 你能详细说明一下函数 f()

标签: scala tuples pattern-matching


【解决方案1】:

你需要与Some进行模式匹配:

def findIntPair(x: Int, y: Int): (Int, Int) = {
    (f(x), f(y)) match {
      case (None, None) || (None, _) || (_, None)  => fail("Unable to find the pair" )
      case (Some(a), Some(b)) => (a, b)
    } 
}

使用包罗万象的case _ 更简洁:

def findIntPair(x: Int, y: Int): (Int, Int) = {
    (f(x), f(y)) match {
      case (Some(a), Some(b)) => (a, b)
      case _  => fail("Unable to find the pair" )
    } 
}

【讨论】:

  • case _ 等价于case (None, None) || (None, _) || (_, None) ?
  • @SLN:它将匹配所有内容,因此在这种情况下,所有不是 (Some(a), Some(b)) 的内容(因为上面已经有匹配的情况)。请注意,它必须是最后一个选项。
【解决方案2】:

我认为正确的解决方案是你这样做:

   (f(x), f(y)) match {
     case (None, None) | (None, _) | (_, None)  => fail("Unable to find the pair" )
     case (Some(a), Some(b)) => (a, b) 
   }
 }

【讨论】:

    【解决方案3】:

    那是因为:

    def findIntPair(x: Int, y: Int): (Int, Int) = {
        (f(x), f(y)) match {
          case (None, None) || (None, _) || (_, None)  => fail("Unable to find the pair" )
          case (a, b) => (a.get, b.get) //here f(x) = a and f(y) = b
        } 
    }
    

    你想要这样的东西:

    def findIntPair(x: Int, y: Int): (Int, Int) = {
    (f(x), f(y)) match {
      case (None, None) || (None, _) || (_, None)  => fail("Unable to find the pair" )
      case (Some(a), Some(b)) => (a, b)
    } 
    

    }

    但这不是最好的方法,我认为这样做更好:

    def findIntPair(x: Int, y: Int): (Int, Int) = {
    
        if(f(x).isDefined && f(y).isDefined) (f(x).get,f(y).get)
        else fail("Unable to find the pair" )
    
    }
    

    【讨论】:

    • 感谢您修复第一个错误。您仍然需要修复“更好”的解决方案,以便它返回 f 的结果而不是输入值。
    【解决方案4】:

    这是表达这种逻辑的另一种方式:

    def findIntPair(x: Int, y: Int): Option[(Int, Int)] =
      for {
        a <- f(x)
        b <- f(y)
      } yield (a,b)
    

    如果f(x) 返回None,它不会计算f(y)。此版本返回一个Option,以便稍后处理错误,但您可以像这样在函数内部进行处理:

    def findIntPair(x: Int, y: Int): (Int, Int) =
      (
        for {
          a <- f(x)
          b <- f(y)
        } yield  (a, b)
      ).getOrElse(fail("Unable to find the pair"))
    

    请注意,这假定fail 返回(Int, Int),这是问题中的代码正常工作所必需的。

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 2021-08-12
      • 1970-01-01
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-27
      相关资源
      最近更新 更多