If you are using the asterisk (*
) symbol in Rust, you are using the dereference unary operator to get the value of reference without the need of getting the reference that maps to the value stored in memory.
However, there is a possibility you have tried to dereference a type in Rust just to come across a similar error like this error[E0614]: type MyStruct cannot be dereferenced
or this error[E0614]: type {integer} cannot be dereferenced
? Maybe your code looks similar to this:
struct MyStruct {
value: i32,
another_value: String,
}
fn dereferencing_structs() {
let my_struct = MyStruct {
value: 1,
another_value: String::from("a"),
};
let my_value = *my_struct; // this will generate the error "error[E0614]: type MyStruct cannot be dereferenced"
}
fn dereferencing_integers() {
let number = 1;
let another = *number; // this will generate the error "error[E0614]: type `{integer}` cannot be dereferenced"
}
Don’t worry, this article will help you understand what the solution to this error.
In Rust, to fix the error “type cannot be dereferenced” you must implement the std::ops::Deref
trait to the type you are attempting to dereference as the type doesn’t have that trait implemented by default. This error occurs often when Rust developers generate their custom structs. Here is an example that shows how to implement the std::ops::Deref
trait.
use std::ops::Deref;
struct MyStruct {
value: i32,
another_value: String,
}
impl Deref for MyStruct {
type Target = i32;
fn deref(&self) -> &Self::Target {
&self.value
}
}
Once implemented, the logic inside the dereferencing_structs
will compile successfully.
fn dereferencing_structs() {
let my_struct = MyStruct {
value: 1,
another_value: String::from("a"),
};
let my_value = *my_struct;
// There are no errors in this line anymore as the
// std::ops::Deref is implemented in the MyStruct struct
}
In a similar way, primitive types such as bool, char, f32, f64, i128, i16, i32, i64, i8, isize, str, u128, u16, u32, u64, u8, and usize, don’t implement the std::ops::Deref
trait by default. A workaround for this is to wrap the value of the type inside a struct and implement the std::ops::Deref
trait. Here is an example of a struct generated for the i32 type.
use std::ops::Deref;
struct Number {
value: i32
}
impl Number {
fn new(value: i32) -> Number {
Number { value: value }
}
}
impl Deref for Number {
type Target = i32;
fn deref(&self) -> &Self::Target {
&self.value
}
}
fn dereferencing_values() {
let number = Number::new(2);
let value = *number;
}
Now, although this solution works for dereferencing a primitive type, the reality is this is overengineered and unnecessary. If what you are looking for is to get a copy of a primitive type value, you could generate a duplicate by copying or cloning the value.
fn no_need_to_dereference() {
let number = 1;
let copied_number = number;
let cloned_numebr = number.clone();
}
Did this article help you fix the error in Rust?
Share your thoughts by sending a message on Twitter of Become A Better Programmer or to my Twitter account!