Should I use references for pointing to objects in another struct?

I am trying to architecture an application containing a gallery, showing pictures, and a cache (or storage) containing the actual pictures.

The Idea is, that the gallery displays the pictures from the cache without copying to but just by referencing to them.
Here is a diagram:

cache_gallery

The pictures in the gallery can than be changed by making them point to another picture in the cache. So the gallery must be used as mutable for this. The Cache is build at startup and not modified afterwards.

I though, with the correct lifetime annotation that should work!
Now, in my first tests I put the cache and gallery inside the same object.
I get the "self-referential struct" problem, as I have learned in this thread.

What is a good way of doing this in rust? Is it fine if I keep the objects separated?
Should I use some other type of reference type?
Should I create my own reference concept? (as in giving the images ids and storing the id).

Since you know that the Cache would not change in future, this would be both convenient and efficient.

The two main solutions are:

  1. Store an id of the image.
  2. Store the image in an Arc and use that to share it.

The main difference is that the Arc will keep the image alive even if removed from the cache as long as an Arc to it exists.

2 Likes

If you're sure the gallery won't be changed for the lifetime of the process, then you can leak it.

let do_whatever_you_want_gallery = Box::leak(Box::new(gallery))

and then you can use &'static references to images in the gallery, even within the same struct. This is at a cost of inability to release memory of any of the images.

However, Arc<Image> is usually fine for this. Arc is a type of a shared reference, but it's not limited to a scoped lifetime.

1 Like

Maybe I'm missing something, but I don't see why plain old &'a Image references wouldn't be an option as well. If the image cache is created at startup and never changed, and you separate the Gallery struct from the Cache struct, then I don't see any reason why you couldn't do something like:

pub struct Gallery<'a> {
    images: Vec<&'a Image>,
}

Using lifetimes is a bit advanced for someone new to Rust, but it seems like a valid option for this specific use case.

2 Likes

You are right that there are some circumstances where it would be possible to use references, but explaining the exact circumstances where that would and would not work would take some time, and the id and Arc based approaches are just simpler and easier to wrap your head around.

This will have ergonomics issues because the 'a lifetime will infect anything that wants to use an Image from your cache. I would rather put things in an Arc because then you know the thing can be passed around and stored for as long as you want without worrying about it outliving the cache.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.