如何在编译时静态注册结构? [英] How can I statically register structures at compile time?

查看:56
本文介绍了如何在编译时静态注册结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找在编译时静态注册结构的正确方法.

I'm looking for the right method to statically register structures at compile time.

这个要求的起源是有一堆applet 有专门的任务,这样如果我运行myprog foo,它会调用foo小程序.

The origin of this requirement is to have a bunch of applets with dedicated tasks so that if I run myprog foo, it will call the foo applet.

所以我首先定义了一个 Applet 结构:

So I started by defining an Applet structure:

struct Applet {
    name: &str,
    call: fn(),
}

然后我可以这样定义我的 foo 小程序:

Then I can define my foo applet this way:

fn foo_call() {
    println!("Foo");
}
let foo_applet = Applet { name: "foo", call: foo_call };

现在我想注册这个小程序,以便我的 main 函数可以在可用时调用它:

Now I would like to register this applet so that my main function can call it if available:

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();

    match AppletRegistry.get(args[1]) {
        Some(x) => x.call(),
        _ => (),
    }
}

整个过程是关于如何实现 AppletRegistry 以便我可以最好在编译时列出所有可用的小程序.

The whole deal is about how AppletRegistry should be implemented so that I can list all the available applets preferably at compile time.

推荐答案

你不能.

Rust 有意识的设计选择之一是在 main 之前没有代码",因此不支持这种事情.从根本上说,您需要在某处显式调用代码来注册小程序.

One of the conscious design choices with Rust is "no code before main", thus there is no support for this sort of thing. Fundamentally, you need to have code somewhere that you explicitly call that registers the applets.

需要执行此类操作的 Rust 程序只会显式列出所有可能的实现并构造它们的单个静态数组.像这样:

Rust programs that need to do something like this will just list all the possible implementations explicitly and construct a single, static array of them. Something like this:

pub const APPLETS: &'static [Applet] = [
    Applet { name: "foo", call: ::applets::foo::foo_call },
    Applet { name: "bar", call: ::applets::bar::bar_call },
];

(有时,重复的元素可以用宏来简化,在这个例子中,你可以改变它,使名称只被提及一次.)

(Sometimes, the repetitive elements can be simplified with macros, i.e. in this example, you could change it so that the name is only mentioned once.)

理论上,你可以通过像 D 这样的语言在幕后做的事情来实现,但会是特定于平台的,并且可能需要弄乱链接器脚本和/或修改编译器.

Theoretically, you could do it by doing what languages like D do behind the scenes, but would be platform-specific and probably require messing with linker scripts and/or modifying the compiler.

旁白:#[test] 怎么样?#[test] 很神奇,由编译器处理.简短版本是:它的工作是在一个 crate 中找到所有测试并构建所述巨型列表,然后由测试运行器使用它有效地替换你的 main功能.不,您无法做类似的事情.

Aside: What about #[test]? #[test] is magic and handled by the compiler. The short version is: it does the job of finding all the tests in a crate and building said giant list, which is then used by the test runner which effectively replaces your main function. No, there's no way you can do anything similar.

这篇关于如何在编译时静态注册结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆