Rust try!
宏展开Result
。 Ok
值被打开; 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如果是这样,怎么做?
这真的很不错。也许可以概括为解开其他类型,例如Future
和Try
。这比有效的项目完成的要弱但是相似:https://github.com/pelotom/effectful。事实上,我认为你可以使用有效但有效的方法实现这一点,需要将整个块包含在宏中,而try!
使用return
来允许更本地的语法,这可以(可以说)更好。
答案 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项目中,需要在与其使用不同的项目中定义宏。)