0.2.2 |
|
---|---|
0.2.1 |
|
0.2.0 |
|
0.1.1 |
|
0.1.0 |
|
#110 in #impl
646 每月下载量
用于 4 crates
28KB
421 代码行
🚀 添加到您的项目
将以下内容添加到您的 Cargo.toml
[dependencies]
impl_new = "0.2.0"
或者在您的 workspace 中运行此命令
cargo add impl_new
❓ 新函数是什么?
new
函数是一个用于创建结构体新实例的函数。在 Rust 中,使用 new
函数创建结构体新实例是一种常见的模式,而不是直接使用结构体。这是因为在不破坏使用它的代码的情况下,更容易向结构体添加新字段。
👨💻 使用方法
很简单,只需在您的结构体上使用 impl_new::New
proc macro,它将为您生成一个 new
函数。
对于命名字段
#[derive(impl_new::New)]
struct Foo {
name: String,
age: usize,
}
// The generated code will look like this:
// impl Foo {
// pub fn new(name: impl Into<String>, age: Into<usize>) -> Self {
// Self { name: name.into(), age: age.into() }
// }
// }
fn main() {
let foo = Foo::new("Hello", 42usize); // Will use `Into::into` to convert the arguments to the fields types.
assert_eq!(foo.name, "Hello".to_string());
assert_eq!(foo.age, 42);
}
对于未命名字段
注意:对于未命名字段,需要使用
#[impl_new)]
属性。
#[derive(impl_new::New)]
struct Foo(#[impl_new(name = "name")] String, #[impl_new(name = "age")] usize);
// The generated code will look like this:
// impl Foo {
// pub fn new(name: impl Into<String>, age: Into<usize>) -> Self {
// Self(name.into(), age.into())
// }
// }
fn main() {
let foo = Foo::new("Hello", 42usize); // Will use `Into::into` to convert the arguments to the fields types.
assert_eq!(foo.0, "Hello".to_string());
assert_eq!(foo.1, 42);
}
🛹 属性
#[impl_new(name= "name")]
name
选项指定了 new
函数中参数的名称。
注意:对于未命名字段,此属性是必需的。
示例
#[derive(impl_new::New)]
struct User(#[impl_new(name = "username")] String, #[impl_new(name = "age")] i32);
// The generated code will look like this:
// impl User {
// pub fn new(username: impl Into<String>, age: Into<i32>) -> Self {
// Self(username.into(), age.into())
// }
fn main() {
let user = User::new("Hello", 42); // Will use `Into::into` to convert the arguments to the fields types.
assert_eq!(user.0, "Hello".to_string());
assert_eq!(user.1, 42);
}
#[derive(impl_new::New)]
struct User {
#[impl_new(name = "username")]
name: String,
#[impl_new(name = "user_age")]
age: i32,
}
// The generated code will look like this:
// impl User {
// pub fn new(username: impl Into<String>, user_age: Into<i32>) -> Self {
// Self { name: username.into(), age: user_age.into() }
// }
// }
fn main() {
let user = User::new("Hello", 42); // Will use `Into::into` to convert the arguments to the fields types.
assert_eq!(user.name, "Hello".to_string());
assert_eq!(user.age, 42);
}
#[impl_new(default)]
default
选项将从 new
函数参数中删除字段,并使用字段类型的默认值。
注意:此选项与
name
选项冲突,因为字段将从new
函数参数中删除。
示例
#[derive(impl_new::New, Default, Debug, PartialEq)]
struct User {
name: String,
#[impl_new(default)]
is_admin: bool,
}
// The generated code will look like this:
// impl User {
// pub fn new(name: impl Into<String>) -> Self {
// Self { name: name.into(), is_admin: bool::default() }
// }
// }
#[derive(impl_new::New)]
struct Foo(#[impl_new(name = "somthing")] String, #[impl_new(default)] User);
// The generated code will look like this:
// impl Foo {
// pub fn new(somthing: impl Into<String>) -> Self {
// Self(somthing.into(), User::default())
// }
// }
fn main() {
let user = User::new("Hello"); // Will use `Into::into` to convert the arguments to the fields types.
let some_foo = Foo::new("Hello"); // Will use `Into::into` to convert the arguments to the fields types.
assert_eq!(user.name, "Hello".to_string());
assert_eq!(user.is_admin, false);
assert_eq!(some_foo.0, "Hello".to_string());
assert_eq!(some_foo.1, User::default());
}
#[impl_new(value=|| <VALUE>)]
选项value
会将字段值设置为给定的值。
注意:此选项与
name
和default
选项冲突,因为字段将从new
函数参数中删除。
注意:值必须是一个返回字段类型的闭包。
示例
#[derive(impl_new::New)]
struct User {
name: String,
#[impl_new(value = || true)]
is_active: bool,
}
// The generated code will look like this: (Not exactly, but you get the idea)
// impl User {
// pub fn new(name: impl Into<String>) -> Self {
// Self { name: name.into(), is_active: true }
// }
// }
#[derive(impl_new::New)]
struct Foo(#[impl_new(name = "name")] String, #[impl_new(value = || true)] bool);
// The generated code will look like this: (Not exactly, but you get the idea)
// impl Foo {
// pub fn new(name: impl Into<String>) -> Self {
// Self(name.into(), true)
// }
// }
fn main() {
let user = User::new("Bob"); // Will use `Into::into` to convert the arguments to the fields types.
let some_foo = Foo::new("Bob"); // Will use `Into::into` to convert the arguments to the fields types.
assert_eq!(user.name, "Bob".to_string());
assert_eq!(user.is_active, true);
assert_eq!(some_foo.0, "Bob".to_string());
assert_eq!(some_foo.1, true);
}
🤗 贡献
欢迎贡献!您可以通过多种方式贡献,例如
- 改进文档。
- 添加更多测试。
- 添加更多示例。
- 通过创建问题来报告错误。
- 通过创建问题来建议新功能。
- 修复错误或添加新功能。(如果您想添加新功能或修复尚未有问题的错误,请先创建一个问题。)
- 修复错别字。
- 重构代码。
- 改进错误信息。
🤝 行为准则
我们致力于为所有人提供一个友好、安全和欢迎的环境。请阅读并尊重行为准则。
📝 变更日志
查看CHANGELOG.md。
🔑 许可证
本项目采用MIT许可证。
依赖项
~0.6–1.1MB
~24K SLoC