mutable-constant

Crates.iomutable-constant
lib.rsmutable-constant
version0.1.0
sourcesrc
created_at2023-05-11 15:53:31.053297
updated_at2023-05-12 11:13:45.202163
descriptionMutable access to a constant value
homepagehttps://github.com/panthios/rscore/tree/master/mutable-constant
repositoryhttps://github.com/panthios/rscore
max_upload_size
id862221
size23,505
Carlos Kieliszewski (carlosskii)

documentation

https://docs.rs/mutable-constant

README

mutable-constant

This crate provides a smart pointer that allows mutation even when the pointer is immutable.

This crate is very new. While it is unlikely to drastically change, it is not yet ready for production use.

Why would you want this?

Consider the following example:

let mut x = 0;
let y = &x;

// Error: `x` already borrowed as immutable
x += 1;

In this example, x is the clear owner of a value, and y wants to reference the value for later. In most cases, this error is justified, since y could change unexpectedly somewhere else. However, in this case, we want to know when x changes through y. The common solution is to use something like Cell or RefCell:

let x = Cell::new(0);
let y = &x;

x.set(x.get() + 1);

This works, but it's not very ergonomic. Cell and RefCell are also not very efficient, since they use runtime checks to ensure that the value is not borrowed mutably. There are a few situations where this is not acceptable:

  • You want the zero-cost abstraction of a basic reference
  • The value is generally immutable, but can change in specific situations. Other than those cases, the value should be immutable, and that fact should be enforced by the compiler.
  • You want a cleaner solution that clearly communicates your intent, including possible mutations and the lifetime of the value.

This crate provides a solution to these problems. It is not a RefCell alternative. Instead, it is a cheaper alternative to shared mutability in general, where mutable references are either compiler-enforced or explicitly unsafe. Here's how it could be used in the above case:

use mutable_constant::Mc;

let x = Mc::new(0);
let y = &x;

// This is unsafe, since `x` is already referenced
unsafe {
  *x.as_defiant_mut() += 1;
}
Commit count: 36

cargo fmt