1 个不稳定版本
0.1.0 | 2022年4月4日 |
---|
#10 在 #keyword
28KB
497 行(不包括注释)
Rust默认和关键字宏
示例
使用默认参数的基本示例
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在解析和宏生态系统方面做出的出色工作
- syn
- quote
- cargo-expand
- 以及许多人!
许可证
MIT或Apache许可证,版本2.0,任选其一。
依赖项
~1–8.5MB
~79K SLoC