#default #kwargs #keyword #default-value

default_kwargs

这个宏可以让你在Rust中使用默认和关键字参数

1 个不稳定版本

0.1.0 2022年4月4日

#10#keyword

MIT/Apache

28KB
497 行(不包括注释)

Rust默认和关键字宏

github Crates.io docs.rs GitHub Workflow Status

示例

使用默认参数的基本示例

use default_kwargs::{default_args, keyword_args};

default_args! {
    fn thing(x: i32, y: i32 = 42) -> (i32, i32) {
        (x, y)
    }
}

fn main() {
    let (r, s) = keyword_args! { thing(42) };
    assert_eq!(r, 42);
    assert_eq!(s, 42);

    let (r, s) = keyword_args! { thing(42, y = 666) };
    assert_eq!(r, 42);
    assert_eq!(s, 666);
}

与大多数具有此功能的语言一样,位置参数必须先于具有默认值的任何参数。

限制

  • 不支持可变参数(例如:fn foo(a: f64, ...)

  • 复杂的模式不工作,例如:Point(x, y): Point = Point(5, 20)会产生错误。

  • 您必须仅使用关键字传递默认参数。也就是说,您不能这样做

    use default_kwargs::{default_args, keyword_args};
    
    default_args! {
        fn foo(x: f64 = 3.14) {}
    }
    
    fn main() {
        keyword_args! { foo(2.71) } // error, do `foo(x = 2.71)` instead.
    }
    
  • 至少到目前为止,您在keyword_args宏中需要使用完整的函数路径。原因是无法从函数的名称获取参数结构的完整路径。这可能在将来发生变化。

它是如何工作的

基本上,default_args宏生成一个新的结构体,并基于函数的名称为其实现Default。上面的示例展开为大致这样

struct ThingArgs {
    y: i32,
}

impl Default for ThingArgs {
    fn default() -> Self {
        Self { y: 42 }
    }
}

fn thing(x: i32, ThingArgs { y }: ThingArgs) -> (i32, i32) {
    (x, y)
}

keyword_args则相反

fn main() {
    let (r, s) = thing(
        42,
        ThingArgs {
            ..ThingArgs::default()
        },
    );
}

致谢

感谢@dtolnay在解析和宏生态系统方面做出的出色工作

许可证

MITApache许可证,版本2.0,任选其一。

依赖项

~1–8.5MB
~79K SLoC