Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scala选项互斥值_Scala - Fatal编程技术网

scala选项互斥值

scala选项互斥值,scala,Scala,我有一个 val file: Option = xxxx val request: Option = yyyyy 这些都是相互排斥的,所以我想要的自然是一种理解。有没有干净的方法 如果两者都不存在,则引发验证异常 如果两者都是(x),则引发验证异常 处理一个或另一个 我认为元组上的匹配可能是最干净的,但我想知道是否有一些map或flatMap recoverWith/rescue技巧看起来可读且简单。好吧,这里有: val result = List(file, request).flatte

我有一个

val file: Option = xxxx
val request: Option = yyyyy
这些都是相互排斥的,所以我想要的自然是一种理解。有没有干净的方法

  • 如果两者都不存在,则引发验证异常
  • 如果两者都是(x),则引发验证异常
  • 处理一个或另一个
  • 我认为元组上的匹配可能是最干净的,但我想知道是否有一些map或flatMap recoverWith/rescue技巧看起来可读且简单。

    好吧,这里有:

    val result = List(file, request).flatten
    if (result.length != 1) throw(...) else [do something with result.head]
    
    或稍微干净一点:

    List(file, request).flatten match { case x::Nil => x ; case _ => throw (...)}
    

    但这两种方法都不是表达您意图的明确方式,因此我也不确定是否推荐。

    我建议将文件和请求的2个VAL转换为一个或两个构造。要做到这一点,我的首选方法是使用模式匹配,正如其他用户在这里已经建议的那样

    当您将代码接收到一个非此即彼的参数,而不是两个参数时,您将确保其中只有一个参数存在,这将允许您编写一个更实用的代码

    在使用了其中一个之后,可以对其使用.fold(handleFileFunc,handleReqFunc)方法

    def handleFileFunc(f: File) = ???
    def handleReqFunc(r: Request) = ???
    
    val data: Either[File, Request] = ???
    
    data fold (handleFileFunc, handleReqFunc)
    

    您可以使用模式匹配,尽管它不能很好地扩展以添加更多选项

    (file, request) match {
      case (Some(f), None) => // handle file
      case (None, Some(r)) => // handle request
      case (None, None) => // error case
      case (Some(_), Some(_)) => // error case
    }
    
    但是,如果你真的可以把“全部无”作为唯一的错误案例,而不是在多个错误案例上出错,那么你可以很容易地将它们按你喜欢的顺序排列,只处理最重要的一个不是无的错误案例-

    // file is more important, ignore request unless file is None
    Seq(file, request).flatten.headOption match {
      case Some(x) => // x is either file or request's value
      case None => // All None, error
    }
    

    这还不够简单易读:

    (x filter (_ => y.isEmpty)) orElse (y filter (_ => x.isEmpty)) orElse ???
    

    正如其他回答所暗示的那样,我认为没有简单的方法。在这种情况下,我想创建一个新的de构造函数(不应用)。它将使意图清晰,并保持代码整洁

    object Xor {
      def unapply[T](p: (Option[T], Option[T])): Option[T] = p match {
        case (None, b @ Some(_)) => b
        case (a @ Some(_), None) => a
        case _ => None
      }
    }
    
    val file: Option[Int] = ???
    val request: Option[Int] = ???
    (file, request) match {
      case Xor(x) => // use x
      case _      => // error
    }
    

    使用一种新的方法不是更清晰吗?