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

如何在Raku中动态导出类?Physics::Measure模块改造咨询

解决Raku中动态声明并导出Physics::Measure子类的问题

你原本通过静态声明子类的方式可以正常工作,但动态创建时遇到编译错误,核心原因是Raku要求类名在编译时必须确定,而::($name)中的变量是运行时值,无法满足编译时要求。下面是针对你需求的解决方案:

(i) 动态声明类的最佳方式

使用Raku的元编程API Metamodel::ClassHOW 来动态创建类,这种方式比EVAL更安全且符合Raku的元编程规范:

unit module Physics::Measure;

# 你的Measure基类定义
class Measure {
    # 这里是Measure类的实现,比如单位处理逻辑等
}

my @type-names = <Length Mass Current>;

for @type-names -> $class-name {
    # 创建类的元对象,指定类名和父类
    my $class-meta = Metamodel::ClassHOW.new_type(
        name => $class-name,
        is   => Measure
    );
    # 完成类的构建(生成方法、属性等)
    $class-meta.^compose;
    # 将类绑定到当前模块的命名空间,方便后续导出和内部使用
    OUR::($class-name) := $class-meta;
}

(ii) 导出这些动态类的最佳方式

由于动态创建的类无法使用编译时的is export属性,需要通过自定义EXPORT子例程来完成导出:

unit module Physics::Measure;

class Measure { ... }

my @type-names = <Length Mass Current>;
my %dynamic-classes;

# 先动态创建类并存储到哈希
for @type-names -> $class-name {
    my $class-meta = Metamodel::ClassHOW.new_type(
        name => $class-name,
        is   => Measure
    );
    $class-meta.^compose;
    OUR::($class-name) := $class-meta;
    %dynamic-classes{$class-name} = $class-meta;
}

# 定义EXPORT子例程,返回包含所有动态类的Map
sub EXPORT {
    Map.new: %dynamic-classes;
}

客户端使用方式

和你原来的用法完全一致,无需修改:

use Physics::Measure;

say my Length $b = 15m; # 输出15m

替代方案:使用EXPORT::DEFAULT包

如果你更倾向于用EXPORT::DEFAULT的方式,也可以这样写:

my package EXPORT::DEFAULT {
    for @type-names -> $class-name {
        # 将动态类绑定到默认导出包的命名空间
        OUR::($class-name) := %dynamic-classes{$class-name};
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:05:17