#default #arguments #macro #args #named #path #zero

default-args

Rust中的零成本默认参数

2 个版本 (1 个稳定版)

1.0.0 2021年8月23日

过程宏 中排名第 595

Download history 21/week @ 2024-03-11 27/week @ 2024-03-18 28/week @ 2024-03-25 67/week @ 2024-04-01 19/week @ 2024-04-08 19/week @ 2024-04-15 22/week @ 2024-04-22 24/week @ 2024-04-29 24/week @ 2024-05-06 29/week @ 2024-05-13 29/week @ 2024-05-20 22/week @ 2024-05-27 24/week @ 2024-06-03 17/week @ 2024-06-10 16/week @ 2024-06-17 26/week @ 2024-06-24

每月下载量 84
3 个 库中使用

MIT 许可证

22KB
322

Rust中的默认参数

Github Actions Github Releases crate.io MIT License

通过宏以零成本启用Rust中的默认参数。只需将函数用 default_args! 包装,就会自动生成具有函数名称的宏,以用于默认参数。下面是使用示例

use default_args::default_args;

// this would make a macro named `foo`
// and original function named `foo_`
default_args! {
    fn foo(important_arg: u32, optional: u32 = 100) -> String {
        format!("{}, {}", important_arg, optional)
    }
}

// in other codes ...
assert_eq!(foo!(1), "1, 100"); // foo(1, 100)
assert_eq!(foo!(1, 3), "1, 3"); // foo(1, 3)
assert_eq!(foo!(1, optional = 10), "1, 10"); // foo(1, 10)

// let's make another one
default_args! {
    #[inline]
    pub async unsafe extern "C" fn bar<S1, S2, S3>(a: S1, b: S2 = "b", c: S3 = "c") -> String
    where
        S1: AsRef<str>,
        S2: AsRef<str>,
        S3: AsRef<str>,
    {
        format!("{}, {}, {}", a.as_ref(), b.as_ref(), c.as_ref())
    }
    // that was long signature!
}

// in other codes ...
assert_eq!(unsafe { bar!("a") }.await, "a, b, c");
assert_eq!(unsafe { bar!("a", "d") }.await, "a, d, c");
// you can even mix named & unnamed argument in optional arguments
assert_eq!(unsafe { bar!("a", "d", c = "e") }.await, "a, d, e");
assert_eq!(unsafe { bar!("a", c = "e") }.await, "a, b, e");

查看更多示例信息:示例

更多功能

导出

在函数前添加导出,宏将被导出。(导出具有宏的函数时添加pub)

default_args! {
    export pub fn foo() {}
}

上述宏将展开如下

pub fn foo_() {}

#[macro_export]
macro_rules! foo { () => {}; }

函数路径

宏只是调用名称中的函数,因此您应该导入宏和函数才能使用它。通过编写此函数的路径,您可以仅导入宏。 (路径应以 crate 开头)

#[macro_use]
pub mod foo {
    default_args! {
        pub fn crate::foo::bar() {}
    }
}

// then it would create `bar!()`
bar!();

上述宏将展开如下

pub mod foo {
    pub fn bar_() {}

    macro_rules! bar_ {
        () => {
            $crate::foo::bar_()
        };
    }
}

为什么我们必须编写模块?

std::module_path! 可以解析函数声明的模块路径。然而,它只能在运行时解析,而不是在编译时。我找不到一种在编译时获取模块路径的方法。

许可证

MIT许可证

依赖关系

~1.5MB
~35K SLoC