Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we call the vec macro using square brackets instead of the parenthesis it is defined with?

Tags:

macros

rust

I am learning Rust macros and am confused about the syntax while using vec. The source code implementing vec!:

macro_rules! vec {
    ($elem:expr; $n:expr) => (
        $crate::vec::from_elem($elem, $n)
    );
    ($($x:expr),*) => (
        <[_]>::into_vec(box [$($x),*])
    );
    ($($x:expr,)*) => (vec![$($x),*])
}

Let's forget the standard way to use it:

let v0 = vec![1, 2, 3];

If we look at the source code, shouldn't we use it like below?

let v1 = vec!(3; 1);
let v2 = vec!(1, 2, 3); 

Why do we use [] instead of () in v1 and v2 compared to v0?

like image 201
AntiInsect Avatar asked Jun 05 '19 16:06

AntiInsect


People also ask

What do the square brackets indicate in coding?

What Does Bracket Mean? Brackets, or braces, are a syntactic construct in many programming languages. They take the forms of "[]", "()", "{}" or "<>." They are typically used to denote programming language constructs such as blocks, function calls or array subscripts.

How do you define a macro in Rust?

We use a dollar sign ( $ ) to declare a variable in the macro system that will contain the Rust code matching the pattern. The dollar sign makes it clear this is a macro variable as opposed to a regular Rust variable.

Why does Rust use macros?

Rust has excellent support for macros. Macros enable you to write code that writes other code, which is known as metaprogramming. Macros provide functionality similar to functions but without the runtime cost. There is some compile-time cost, however, since macros are expanded during compile time.

What is derive macro in Rust?

Derive macros These macros can create new items given the token stream of a struct, enum, or union. They can also define derive macro helper attributes. Custom derive macros are defined by a public function with the proc_macro_derive attribute and a signature of (TokenStream) -> TokenStream .


1 Answers

As you note, you can use parenthesis, square brackets, or curly braces to call a macro:

let a = vec!(0, 1, 2);
let b = vec![0, 1, 2];
let c = vec! { 0, 1, 2 };

Macros don't care about which of these syntaxes you use1. Programmers care about which syntax you use.

Rust's array and slicing syntax uses square brackets and Vecs are highly related to both of these. Using square brackets for constructing a Vec is simply the language convention. Rustfmt will automatically convert calls to vec! into square brackets.


1 - There's a small interaction between which brace style you use when invoking a macro and semicolons. A macro used as an item or statement is required to end with a semicolon if it doesn't use curly braces:

macro_rules! dummy {
    () => {};
}

// Not OK
dummy!()

// OK
dummy! {} 

// OK
dummy!();
like image 73
Shepmaster Avatar answered Oct 20 '22 21:10

Shepmaster