gpt4 book ai didi

Scala 宏 - 使用 `c.prefix` 推断隐式值

转载 作者:行者123 更新时间:2023-12-04 18:37:18 24 4
gpt4 key购买 nike

c.inferImplicitValue推断调用站点范围内的隐式值。是否可以使用 c.prefix 来推断隐式?范围?

这不是有效的代码,但表达了我的需要:

c.prefix.inferImplicitValue

我目前为此目的使用了一个简单的实现[1],但它有一些限制,比如不能从 def 推断隐式值。 s 并检测重复/模糊的隐含值。

[1] https://github.com/getquill/quill/blob/9a28d4e6c901d3fa07e7d5838e2f4c1f3c16732b/quill-core/src/main/scala/io/getquill/util/InferImplicitValueWithFallback.scala#L12

最佳答案

只需使用适当的(本地)导入生成一个块,然后调用 implicitly诀窍:

q"""{import ${c.prefix}._; _root_.scala.Predef.implicitly[$T] }

哪里 TType 的一个实例表示要查找的隐式值的类型。

要检查隐式查找是否真的成功,您可以调用 Context.typeChecksilent=true并检查结果树是否为空。

作为说明,这是一个实现 infer 的示例。方法返回 None如果在目标对象的成员中没有找到隐式,否则将结果包装在 Some 中.
import scala.reflect.macros.Context
import scala.language.experimental.macros

def inferImplicitInPrefixContext[T:c.WeakTypeTag](c: Context): c.Tree = {
import c.universe._
val T = weakTypeOf[T]
c.typeCheck(
q"""{
import ${c.prefix}._
_root_.scala.Predef.implicitly[$T]
}""",
silent = true
)
}

def infer_impl[T:c.WeakTypeTag](c: Context): c.Expr[Option[T]] = {
import c.universe._
c.Expr[Option[T]](
inferImplicitInPrefixContext[T](c) match {
case EmptyTree => q"_root_.scala.None"
case tree => q"_root_.scala.Some($tree)"
}
)
}

trait InferOp {
def infer[T]: Option[T] = macro infer_impl[T]
}

让我们测试一下:
object Foo extends InferOp {
implicit val s = "hello"
}

Foo.infer[String] // res0: Some[String] = Some(hello)

Foo.infer[Int] // res1: None.type = None

implicit val lng: Long = 123L

Foo.infer[Long] // res2: Some[Long] = Some(123)

关于Scala 宏 - 使用 `c.prefix` 推断隐式值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32603946/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com