1 个不稳定版本
0.2.0 | 2021年6月6日 |
---|
#72 在 #stdio
218 每月下载
在 argio 中使用
8KB
172 行
argio
将函数输入输出转换为stdio的宏
此宏将函数的参数和返回值更改为从标准输入和输出中获取。
#[argio]
fn main(n: i32) -> i32 {
n * 2
}
此函数不是接收整数作为参数,而是从标准输入读取整数,并将结果输出到标准输出。
由于此宏使用proconio作为输入的后端,因此您可以将与可以传递给proconio的宏相同的参数放入函数中(即使它们不是Rust的正确语法)。
#[argio]
fn main(n: usize, x: [i64; n]) -> i64 {
x.into_iter().sum()
}
此函数从标准输入读取此类输入
N
x_1 x_2 ... x_N
并将总和输出到标准输出。
您可以通过设置input
参数来更改输入宏。宏将函数的参数原样接收。
macro_rules! my_input {
...
}
#[argio(input = my_input)]
fn main(n: usize, x: [i64; n]) -> i64 {
x.into_iter().sum()
}
由于使用了Display
特质来显示返回值,因此没有实现Display
特质的函数,如Vec
,不能按原样编译。
您可以通过使用实现Display
特质的包装结构来自定义输出的行为。
struct Wrap<T>(T);
impl<T: Display> Display for Wrap<Vec<T>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (ix, r) in self.0.iter().enumerate() {
if ix > 0 {
write!(f, " ")?;
}
r.fmt(f)?;
}
Ok(())
}
}
#[argio]
fn main(n: usize) -> Wrap<Vec<usize>> {
Wrap((0..n).map(|i| i * 2).collect())
}
$ echo 10 | cargo run
0 2 4 6 8 10 12 14 16 18
当然,您也可以手动输出。如果函数的返回值是()
,它不会将任何内容输出到标准输出,因此您可以手动输出它并返回()
。
#[argio]
fn main(n: usize) {
let ans = (0..n).map(|i| i * 2).collect::<Vec<_>>();
for (i, x) in ans.into_iter().enumerate() {
if i > 0 {
print!(" ");
}
print!("{}", x);
}
println!();
}
您还可以从宏参数中指定输出包装器。这的优点是从代码中删除包装器的信息,使您可以将输出自定义移动到代码的模板部分。
#[argio(output = Wrap)]
fn main(n: usize) -> Vec<usize> {
(0..n).map(|i| i * 2).collect()
}
如果指定了multicase
属性,则可以用于自动执行以案例数量开始的多个案例的多个输入。
属性 multicase
的值是一个字符串,用于显示在每个情况的顶部。变量 i
包含从 0 开始的情况编号,因此您可以使用它来自定义显示。
#[argio(multicase = "Case #{i+1}: ", output = Wrap)]
fn main(n: usize) -> Vec<usize> {
(0..n).map(|i| i * 2).collect()
}
$ echo "3 2 3 5" | cargo run
Case #1: 0 2
Case #2: 0 2 4
Case #3: 0 2 4 6 8
许可证:MIT
依赖项
~3.5–4.5MB
~88K SLoC