相当于Rust的尝试! Scala中的宏

时间:2015-05-22 23:07:23

标签: scala scala-macros

Rust try!宏展开ResultOk值被打开; Err会导致封闭方法立即返回Err。在此实施:https://doc.rust-lang.org/std/macro.try!.html

这大致相当于Scala Option.getOrElse(return None)

是否可以在Scala中为Option s编写等效的宏?宏似乎需要检查封闭方法的返回类型是Option。我在这里找到了一些相关的讨论:https://groups.google.com/forum/#!topic/scala-user/BH0xz74f4Zk如果是这样,怎么做?

这真的很不错。也许可以概括为解开其他类型,例如FutureTry。这比有效的项目完成的要弱但是相似:https://github.com/pelotom/effectful。事实上,我认为你可以使用有效但有效的方法实现这一点,需要将整个块包含在宏中,而try!使用return来允许更本地的语法,这可以(可以说)更好。

2 个答案:

答案 0 :(得分:0)

你确定需要一个宏吗? 如果您不想处理异常,而是返回选项,您也可以尝试进行理解。这种方法也适用于期货和trys btw。

def f1(): Option[Int] = ???
def f2(): Option[String] = ???
def f3(): Option[Double] = ???

def test(): Option[String] = {
  for {
    i <- f1()
    s <- f2()
    d <- f3()
  } yield {
    val n = i * 2
    s + (d * n)
  }
}

答案 1 :(得分:0)

我能够通过以下方式(在REPL中)执行此操作:

import scala.language.experimental.macros

def impl[T](c: reflect.macros.whitebox.Context)(opt: c.Expr[Option[T]]): c.Tree = {
  import c.universe._
  q"$opt.getOrElse(return None)"
}

def unwrap[T](opt: Option[T]): T = macro impl[T]

然后我可以按如下方式使用它:

def concat(str1: Option[String], str2: Option[String]): Option[String] = {
  Some(unwrap(str1) + unwrap(str2))
}

concat(Some("hello"), Some(" world")) == Some("hello world")
concat(Some("hello"), None) == None

(请注意,在sbt项目中,需要在与其使用不同的项目中定义宏。)