You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rascal的eval调用自定义代数数据类型报未声明变量错误咨询

报错原因

Rascal 的 eval 函数默认使用独立的干净执行上下文,不会继承当前模块的类型定义、导入依赖,所以你在表达式里用到的 dog、cat 构造函数在 eval 的上下文中没有被声明,就会抛出未定义错误。


解决方案1:继承当前模块上下文(无需在eval内重复导入)

util::Eval 模块的 eval 函数提供了 imports 参数,可以指定 eval 执行时自动导入的模块,你只需要把当前模块的位置传入,就可以复用当前模块所有的定义:

// 仅需修改eval调用行,添加imports参数即可
Result[bool] re = eval(#bool, "[*_, cat(), *_] := [dog(), cat()];", imports={|PuzzleScript::Test::Engine::EvalExample|});

修改后执行即可正常输出 True 2。


解决方案2:避免使用eval的动态模式匹配实现

你不需要依靠拼接字符串+eval实现动态模式匹配,Rascal 支持更安全高效的原生实现方式:

  • 如果是简单的动态匹配目标场景:直接用高阶函数传参即可,比如你需要动态指定要匹配的元素,直接将元素作为参数传入匹配函数:
// 通用列表匹配函数,无需eval
bool hasTarget<T>(list<T> input, T target) {
  return [*_, target, *_] := input;
}

// 调用示例
println(hasTarget([dog(), cat()], cat()) ? "True 2" : "False 2");
  • 如果是复杂度更高的动态模式(比如动态决定匹配位置、匹配规则数量),可以用Rascal的元编程API构造模式语法树,再编译成可执行函数,性能和安全性都远高于eval,同时天然继承当前模块的上下文,不需要额外处理导入问题。

内容的提问来源于stack exchange,提问作者Clement Julia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 21:36:00