对 groovy dsl 的闭包和映射组合进行类型检查

Type checking for closures and map combinations for groovy dsl

提问人:Hsh727js 提问时间:9/14/2022 更新时间:9/30/2022 访问量:96

问:

我目前正在测试Groovy文档中的某些内容。我偶然发现了这个 dsl 的例子。

show = { println it }
square_root = { Math.sqrt(it) }

def please(action) {
  [the: { what ->
    [of: { n -> action(what(n)) }]
  }]
}

// equivalent to: please(show).the(square_root).of(100)
please show the square_root of 100

有没有办法确保“of”操作中的类型是例如具有正确语法突出显示的 int?

如果这是不可能的,有什么方法可以通过适当的类型检查来构建像 dsl 这样的句子?

谢谢!

兹特威斯克

Groovy 闭包 DSL

评论

0赞 emilles 9/16/2022
please 的返回值可以是类型而不是 def。你可以使用一个界面作为第一步,并使用强制,这样你仍然可以使用地图。有一些博客是关于从松散的 dsl (例如)迁移到类型检查的“现代”dsl 的。但是我手头没有链接。
0赞 Hsh727js 9/22/2022
谢谢你的评论。使用类型而不是 def 是个好主意。但是返回类型可能是什么?地图<参考, 地图<参考,...>等?无法真正从调试器获得有关我应该使用哪种类型的良好信息。谢谢!
0赞 emilles 9/22/2022
一个新接口,如“interface I { J the(DoubleFunction what) }”和“interface J { double of(double) }”

答:

0赞 emilles 9/22/2022 #1

通过引入用于返回类型的接口,可以为 IDE 提供推断 dsl 中每个方法的路径。

import java.util.function.*

interface I { J the(DoubleFunction what) }
interface J { double of(Number n) }

def show = { println it }
def square_root = Math.&sqrt

I please(DoubleConsumer action) {
  [the: { DoubleFunction what ->
    [of: { n -> action(what(n)) }] as J
  }] as I
}

// equivalent to: please(show).the(square_root).of(100)
please show the square_root of 100

demonstration of type inferencing

评论

0赞 Hsh727js 9/28/2022
我刚刚测试了它,它说,它不能将映射 [the=...] 转换为接口。不过,语法高亮显示工作正常。
0赞 emilles 9/29/2022
您是否启用了类型检查?
0赞 Hsh727js 9/29/2022
您的意思是 CompileStatic 还是 TypeChecked 作为注释?那么是的。
0赞 emilles 9/30/2022
你不需要类型检查或静态编译来使用please方法。或者,您可以使用“as”将映射强制为接口类型。
0赞 Hsh727js 9/30/2022
我在没有注释和“as”强制的情况下尝试了它,当它尝试将映射转换为接口时,它会抛出“找不到 LinkedHashMap 的匹配构造函数”。我尝试使用 Groovy 2.5 和 3.0