Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何在一个可执行文件中组合不同的算法_Rust - Fatal编程技术网

Rust 如何在一个可执行文件中组合不同的算法

Rust 如何在一个可执行文件中组合不同的算法,rust,Rust,为了学习Rust,我已经开始实施一些项目Euler问题。现在,我想采取下一步,创建一个基于控制台的用户界面,它能够运行所有或只运行特定的问题。另一个要求是,用户应该能够将可选参数仅传递给特定问题 我目前的解决方案是有一个TraitProjectEulerProblem,它声明例如run()。有了它,我可以做这样的事情: fn main() { let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());

为了学习Rust,我已经开始实施一些项目Euler问题。现在,我想采取下一步,创建一个基于控制台的用户界面,它能够运行所有或只运行特定的问题。另一个要求是,用户应该能够将可选参数仅传递给特定问题

我目前的解决方案是有一个Trait
ProjectEulerProblem
,它声明例如
run()
。有了它,我可以做这样的事情:

fn main() {
    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());

    let problems: Vec<Box<problems::ProjectEulerProblem>> = vec![
        box problems::Problem1,
        box problems::Problem2
    ];

    match args.flag_problem {
        Some(x) => println!("Result of problem: {} is {}", x, problems[x-1].run()),
        None    => println!("No problem number given.")
    }
}
fn main(){
让args:args=args::docopt().decode().unwrap_或_else(| e | e.exit());
让问题:Vec=Vec[
盒子问题::问题1,
盒子问题::问题2
];
匹配args.flag_问题{
Some(x)=>println!(“问题的结果:{}是{}”,x,问题[x-1]。run()),
无=>println!(“未给出问题编号”)
}
}
我的问题是,有没有办法摆脱显式的
问题
向量初始化,也许可以使用宏?也欢迎您提供上述实现我的应用程序的替代方案。

您可以使用生成列表,而无需每次键入完整的路径和名称

macro_rules! problem_vec(
    ($( $prob:tt ),*) => ({
        &[
            $(
                &concat_idents!(Proble, $prob),
            )*
        ]
    });
);
const PROBLEMS: &'static[&'static ProjectEulerProblem] = problem_vec!(m1, m2);
注意,不能简单地使用索引,因为
concat_idents
宏需要标识符,而数字不是标识符<代码>concat_idents
也仅在夜间提供。在stable上,您需要给出整个结构的名称:

macro_rules! problem_vec(
    ($( $prob:ident ),*) => ({
        &[
            $(
                &problems::$prob,
            )*
        ]
    });
);

const PROBLEMS: &'static [&'static problems::ProjectEulerProblem] = problem_vec!(
    Problem1, Problem2
);

我的板条箱可以让您定义一种简洁的方法,将问题数组构建为
问题![1,2]
。此方法适用于任何大于等于1.15.0的版本



因此,您只想指定问题的总数,而不是问题的全名,或者您可以使用需要列出所有问题编号的宏,如
[1,2]
。在您的情况下,我认为使用
[1,2]
的宏目前应该可以。@kunerd:这样写出来时,使用
Vec
是不必要的,需要分配;它可以完全静态地定义,
&'static[&'static Problem]
#[macro_use]
extern crate mashup;

mod problems {
    pub trait ProjectEulerProblem {
        fn run(&self);
    }

    pub struct Problem1;
    impl ProjectEulerProblem for Problem1 {
        fn run(&self) {
            println!("running Project Euler problem 1");
        }
    }

    pub struct Problem2;
    impl ProjectEulerProblem for Problem2 {
        fn run(&self) {
            println!("running Project Euler problem 2");
        }
    }
}

macro_rules! problems {
    ($($number:tt),*) => {{
        // Use mashup to define a substitution macro `m!` that replaces every
        // occurrence of the tokens `"Problem" $number` in its input with the
        // concatenated identifier `Problem $number`.
        mashup! {
            $(
                m["Problem" $number] = Problem $number;
            )*
        }

        // Invoke the substitution macro to build a slice of problems. This
        // expands to:
        //
        //     &[
        //         &problems::Problem1 as &problems::ProjectEulerProblem,
        //         &problems::Problem2 as &problems::ProjectEulerProblem,
        //     ]
        m! {
            &[
                $(
                    &problems::"Problem" $number as &problems::ProjectEulerProblem,
                )*
            ]
        }
    }}
}

fn main() {
    for p in problems![1, 2] {
        p.run();
    }
}