scala - call-by-name function is evaluated before invoke
问题描述
I have a logic look like this:
def process[T](f1: => T, f2: => T): T = {
Try { /*Do Something*/ } match {
case Failure(_) => Try { /*Do something*/ } match {
case Failure(e) => throw e
case Success(v1) =>
// I just need this succeed value be passed to my f1
// but I dont know how. So...
implicit val v: V1 = v1
f1
}
case Success(v2) =>
// I just need this succeed value be passed to my f1
// but I dont know how. So...
implicit val v: V2 = v2
f2
}
then I define f1
and f2
and call this process
function like this:
// just for describing this problem clearly
// V1, V2 are two successful output types from the above snippet's branches.
// They are two different types.
// Bar just a dummy Object, Unit will do the same
// I use Bar(v) just to show I processed v in this function.
def f1(implicit v: V1): Bar = Bar(v)
def f2(implicit v: V2): Bar = Bar(v)
process(f1, f2)
then I got error that says No implicit found for f1
. Any Help?
解决方案
隐式并不像你想象的那样工作。您必须传递隐式函数类型而不是按名称参数,但 Dotty 中引入了隐式函数类型:
// if it was Dotty
def process[T](f1: (given V1) => Bar, f2: (given V2) => Bar) = ...
Scala 2 中没有类似的结构。最接近的近似值是手写trait
的,带有apply
隐式参数。
trait F1 { def apply()(implicit v: V1): Bar }
trait F2 { def apply()(implicit v: V2): Bar }
def process[T](f1: F1, f2: F2): T = {
Try { /*Do Something*/ } match {
case Failure(_) => Try { /*Do something*/ } match {
case Failure(e) => throw e
case Success(v1) =>
implicit val v: V1 = v1
f1()
}
case Success(v2) =>
implicit val v: V2 = v2
f2()
}
def f1: F1 = new F1 { def apply()(implicit v: V1): Bar = Bar(v) }
def f2: F2 = new F2 { def apply()(implicit v: V2): Bar = Bar(v) }
process(f1, f2)
推荐阅读
- javascript - 我在 web 地图中有一个切片图层,我想创建一个函数来调用切片图层并在切片图层比例更改时返回一个值
- postgresql - 根据分布分配列值
- c# - 未使用自定义授权服务,即使它已在服务中声明
- spring-security - 创建名为“securityTagLib”的 bean 时出错-(grails-spring-security-saml 插件)
- c++ - 如何使用 yaml-cpp 获取序列名称
- javascript - 如何修复将 PHP 变量的值传递给 javascript 变量
- node.js - Discord bot 突然断开连接
- excel - 如果相邻单元格不为空白,则自动编号单元格(1、2、3 等)
- java - 图像未上传到 Java Spring Boot 项目中的 AWS S3 存储桶
- visual-studio - WiX 项目永远不会是最新的