darque
darque

Reputation: 1626

How to write a function (or a macro) to create a Vec and a reference to it?

So I have something like this:

let v = vec![...];
let s = Data { vec: &v, ... };

Perhaps this is misguided, but the idea is that many data structures could share the same vector. But for the case where I don't want to share, it would be convenient to have something like this:

let (v, s) = make_data(...);

Apparently, unlike the first example, there is no way to connect the lifetime of v and s (correct me if I'm wrong). Anyway, I understand the borrow checker rejects this. So I end up doing:

let v = vec![];
let s = make_data(&v, ...);

Now, perhaps, I could make one of those work:

let (v, s) = make_data!(...);
let s = make_data!(v, ...);
let s = make_data!(...);

The problem here is that thse macros would expand to something like { let v = vec![]; ... } and v's destructor will be run in the end of this block, but what I really want is to have it expand to something like the first example.

Now, I can make this work:

make_data!(v, s, ...);

But it's odd. Is there any other way to solve this?

Upvotes: 0

Views: 324

Answers (1)

Francis Gagné
Francis Gagné

Reputation: 65832

Rust allows you to define multiple variables with the same name in the same block.

let a = vec![...];
let a = Data { vec: &a, ... };

On the second line, the new a is not in scope yet, so you can still refer to the previous definition of a. However, on the following statements, you can no longer refer to the original a definition, since the second definition shadows the first one; nevertheless, the Vec remains alive until the end of the block, as usual.

You can take advantage of this in your macro by only taking a single identifier and using it for both the Vec and the slice.

Upvotes: 1

Related Questions