gpt4 book ai didi

scala - Scala 宏的静态返回类型

转载 作者:行者123 更新时间:2023-12-03 07:12:13 26 4
gpt4 key购买 nike

所以我有这个宏:

import language.experimental.macros
import scala.reflect.macros.Context

class Foo
class Bar extends Foo { def launchMissiles = "launching" }

object FooExample {
def foo: Foo = macro foo_impl
def foo_impl(c: Context): c.Expr[Foo] =
c.Expr[Foo](c.universe.reify(new Bar).tree)
}

我已经说过三次我希望 foo 返回 Foo,但我可以执行以下操作(在 2.10.0-RC3 中):

scala> FooExample.foo
res0: Bar = Bar@4118f8dd

scala> res0.launchMissiles
res1: String = launching

如果我删除 c.Expr 上的类型参数,也会发生同样的情况。如果我真的想确保调用 foo 的人看不到他们正在获取 Bar,我必须在树本身中添加类型归属。

这实际上非常棒 - 例如,这意味着我可以将宏指向某种模式,并使用表示词汇表中术语的成员方法创建某个 Vocabulary 类的匿名子类,这些将在返回的对象上可用。

不过,我想确切地了解我在做什么,所以我有几个问题。首先,foo 方法的返回类型实际上是什么?它仅适用于(可选)文档吗?它明显限制了返回类型(例如,在本例中我无法将其更改为 Int),如果我完全删除它,则会收到如下错误:

scala> FooExample.foo
<console>:8: error: type mismatch;
found : Bar
required: Nothing
FooExample.foo
^

但我可以将其更改为Any,并且在调用foo时仍然获得静态类型的Bar

第二,这种行为是否在某处指定?这似乎是一组相当基本的问题,但我无法找到明确的解释或讨论。

最佳答案

此行为未指定但有意为之,尽管它可能看起来令人困惑。我们计划详细说明返回类型在宏签名中的作用,但目前我觉得灵 active 是一件好事。

有时行为也不一致,例如当宏陷入类型推断过程中时,将使用其静态签名(即示例中的 Foo ),而不是实际扩展的类型。这是因为宏扩展被故意延迟,直到类型推断完成(以便宏实现看到推断的类型,而不是类型变量)。这是一种权衡,不一定是最好的,因此我们计划尽快重新审视它:https://issues.scala-lang.org/browse/SI-6755 .

该部门的另一个问题是隐式宏。当隐式宏的返回类型是通用的并且需要从隐式值的请求类型推断时,就会发生不好的事情。这使得目前无法使用宏来生成类型标签:https://issues.scala-lang.org/browse/SI-5923 .

关于scala - Scala 宏的静态返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13669974/

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