Box::new 像vec这样的宏!在生锈
Box::new macro like vec! in Rust
我在 Rust 语言中看到了很多 Box::new
的用法。
https://doc.rust-lang.org/book/ch15-01-box.html
fn main() {
let b = Box::new(5);
println!("b = {}", b);
}
但是,我认为这有点多余,尤其是在这样的代码中:
enum List {
Cons(i32, Box<List>),
Nil,
}
use crate::List::{Cons, Nil};
fn main() {
let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
}
现在,我想使用宏以简洁的方式编写,正如我们所见 vec!
let v: Vec<u32> = vec![1, 2, 3];
所以使用 box!
宏,我们可以写:
fn main() {
let b = box!(5);
println!("b = {}", b);
}
或
fn main() {
let list = Cons(1, box!(Cons(2, box!(Cons(3, box!(Nil))))));
}
我的问题是
box!
宏为什么不流行
在 Rust 中经常使用?
定义宏的正确方法是什么?有什么注意事项吗?
这有点主观,但我相信矢量的使用频率要高得多。与您所指的 box!
宏相比,vec!
宏为您节省了很多代码。
至于宏的实现,可以这样写:
macro_rules! bx {
($e:expr) => {
Box::new($e)
};
}
这是一个用法示例:
let b = Box::new(3);
let m = bx!(7);
请注意,我将其命名为 bx!
而不是 box!
,因为后者是 Rust 中的保留字。
感谢@at54321,我用谷歌搜索并找到了
https://doc.rust-lang.org/beta/unstable-book/language-features/box-syntax.html
#![feature(box_syntax)]
fn main() {
let b = box 5;
}
所以,已经存在了。
however, for some unknown reason Rust guys prefer to use macro for vec! or println!
我建议反过来问:为什么 vec!
和 println!
不能是函数?答案是,两者都是可变的(可以接受可变数量的参数)并且 Rust 中没有可变参数函数。 println!
的情况更糟,它的参数也可以有不同的类型;这些类型的约束取决于第一个参数!试着写下 println
的类型作为一个函数,你会发现它的可用性会大大降低 并且 效率也会降低。
vec!
解决的问题比较小。但正如 Chayim Friedman 的评论所说,直到最近,你甚至还没有
Vec::from([1,2,3])
如果没有 vec!
宏。 我认为你能做的最好的是
Vec::from(&[1,2,3])
正如 Chayim 指出的那样,这比 vec!
.
更糟糕
当然,Box::new
完全没有这个问题。所以它是一个函数只是因为它没有是一个宏。
but as I post the Cons list expample, it's obvious the latter syntax is redundant and does have an issue for readability
在那种情况下,box!
同样是多余的;相反,摆脱冗余的一种方法是
fn cons(head: i32, tail: List) -> List {
List::Cons(head, Box::new(tail))
}
然后
let list = cons(1, cons(2, cons(3, Nil)));
甚至 list!
宏和
let list = list![1,2,3];
我在 Rust 语言中看到了很多 Box::new
的用法。
https://doc.rust-lang.org/book/ch15-01-box.html
fn main() {
let b = Box::new(5);
println!("b = {}", b);
}
但是,我认为这有点多余,尤其是在这样的代码中:
enum List {
Cons(i32, Box<List>),
Nil,
}
use crate::List::{Cons, Nil};
fn main() {
let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
}
现在,我想使用宏以简洁的方式编写,正如我们所见 vec!
let v: Vec<u32> = vec![1, 2, 3];
所以使用 box!
宏,我们可以写:
fn main() {
let b = box!(5);
println!("b = {}", b);
}
或
fn main() {
let list = Cons(1, box!(Cons(2, box!(Cons(3, box!(Nil))))));
}
我的问题是
box!
宏为什么不流行 在 Rust 中经常使用?定义宏的正确方法是什么?有什么注意事项吗?
这有点主观,但我相信矢量的使用频率要高得多。与您所指的 box!
宏相比,vec!
宏为您节省了很多代码。
至于宏的实现,可以这样写:
macro_rules! bx {
($e:expr) => {
Box::new($e)
};
}
这是一个用法示例:
let b = Box::new(3);
let m = bx!(7);
请注意,我将其命名为 bx!
而不是 box!
,因为后者是 Rust 中的保留字。
感谢@at54321,我用谷歌搜索并找到了
https://doc.rust-lang.org/beta/unstable-book/language-features/box-syntax.html
#![feature(box_syntax)]
fn main() {
let b = box 5;
}
所以,已经存在了。
however, for some unknown reason Rust guys prefer to use macro for vec! or println!
我建议反过来问:为什么 vec!
和 println!
不能是函数?答案是,两者都是可变的(可以接受可变数量的参数)并且 Rust 中没有可变参数函数。 println!
的情况更糟,它的参数也可以有不同的类型;这些类型的约束取决于第一个参数!试着写下 println
的类型作为一个函数,你会发现它的可用性会大大降低 并且 效率也会降低。
vec!
解决的问题比较小。但正如 Chayim Friedman 的评论所说,直到最近,你甚至还没有
Vec::from([1,2,3])
如果没有 vec!
宏。 我认为你能做的最好的是
Vec::from(&[1,2,3])
正如 Chayim 指出的那样,这比 vec!
.
当然,Box::new
完全没有这个问题。所以它是一个函数只是因为它没有是一个宏。
but as I post the Cons list expample, it's obvious the latter syntax is redundant and does have an issue for readability
在那种情况下,box!
同样是多余的;相反,摆脱冗余的一种方法是
fn cons(head: i32, tail: List) -> List {
List::Cons(head, Box::new(tail))
}
然后
let list = cons(1, cons(2, cons(3, Nil)));
甚至 list!
宏和
let list = list![1,2,3];