Box::new macro like vec! in Rust
Solution 1:
This is a bit subjective, but vectors are used far more often, I believe. And the vec!
macro saves you a lot more code compared to the box!
macro you are referring to.
As for the macro implementation, you can write something like this:
macro_rules! bx {
($e:expr) => {
Box::new($e)
};
}
Here is an example usage:
let b = Box::new(3);
let m = bx!(7);
Note that I named it bx!
and not box!
, as the latter is a reserved word in Rust.
Solution 2:
however, for some unknown reason Rust guys prefer to use macro for vec! or println!
I suggest asking this the other way around: why couldn't vec!
and println!
be functions? And the answer is, both are variadic (can take variable number of arguments) and there are no variadic functions in Rust. It's much worse for println!
, whose arguments can have different types too; and constraints on those types depend on the first argument! Try writing down a type for println
as a function, and you'll find it would be much less usable and less efficient.
The problem vec!
solves is smaller. But as Chayim Friedman's comment says, until quite recently you couldn't even have had
Vec::from([1,2,3])
if there were no vec!
macro. I think the best you could have done was
Vec::from(&[1,2,3])
As Chayim points out, this is strictly worse than vec!
.
Of course, Box::new
doesn't have this problem at all. So it's a function just because it didn't have to be a macro.
but as I post the Cons list expample, it's obvious the latter syntax is redundant and does have an issue for readability
In that case box!
is no less redundant; instead a way to get rid of redundancy is
fn cons(head: i32, tail: List) -> List {
List::Cons(head, Box::new(tail))
}
and then
let list = cons(1, cons(2, cons(3, Nil)));
Or even a list!
macro and
let list = list![1,2,3];