[Solved] Rust how to make a C++ like * const pointer?


How can I implement the C++ *const pointer in Rust so that I can create a const struct pointer(Node *const head) but the struct field is mutable.

C++ example

class Node{
    int data;
class List{
    Node *const head;

void List::insert(int key){
    Node* tmp = head; // I'm stuck with here.
        if (condition){
            tmp = some_node;
        tmp = tmp->next();
    tmp->data = key; // modify the field.

I tried to use let mut tmp_ptr: *mut Node<T> = &mut self.head; , but it will change the head node which is not I want.



A immutable borrow (&T) coerces into a *const T. Similarly a mutable borrow (&mut T) coerces into a *mut T.

fn takes_raw_const<T>(_: *const T) {}
fn takes_raw_mut<T>(_: *mut T) {}

fn main() {
    let foo = 0;
    takes_raw_mut(&mut foo);
1 Like


You’re asking multiple different questions here.

  • * const: this doesn’t exist in Rust. You cannot write Node *const head; in Rust.

  • *const T: this doesn’t exist in C++, so it has no Rust equivalent.

  • Node *tmp = head; is just let mut tmp = self.head;.

  • “it will change the head node which is not I want”: you can’t modify the Nodes without having mutable access to the List.

It also doesn’t help that your C++ code isn’t complete, referring to things that don’t exist.

If you want to implement a linked list, you should probably read Learning Rust With Entirely Too Many Linked Lists.



Here is an almost direct translation for reference, here is a more idiomatic rust version.

1 Like


I resolved it myself.



You should note that *const and *mut isn’t that really different in Rust. They can trivially be convertible in both directions, even in safe context. *const doesn’t guarantee about immutability, and *mut also doesn’t do so about exclusive access. They’re also treated equally in miri UB checker.

1 Like


See also What is the real difference between *const T and *mut T raw pointers?

1 Like


You’re right, my way is to convert *const T pointer to * mut T pointer.



Thanks for your reply, I’m thinking a lot of the issues discussed here are important for beginners, so why not put them into the documentation?Or did I not find the correct document?



Except for FFI, beginners shouldn’t be using raw pointers! The standard library has a wide number of safe, compostable abstractions for you to use, like Box, Rc, and RefCell.

In all my time writing rust I can only think of one time I’ve used raw pointers for something other than FFI, and that was to pair them with a PhantomData<&mut T> in some type that represented a mutable borrow of non-contiguous data (a matrix slice).



Thanks for your valuable advice.I’ll try other standard way.