Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Program with multiple ampersand works fine [duplicate]

Tags:

rust

The following program works fine:

pub fn foo(_v: &str) -> bool {
    false
}

fn main() {
    let f = "hello world";
    println!("{}", foo(&&&&f)); // note the number of & here
}

In fact it works on passing any number of &. How should I interpret what is going on ?

My rust version:

$ rustc --version
rustc 1.32.0-nightly (13dab66a6 2018-11-05)
like image 363
Sibi Avatar asked Jan 28 '23 04:01

Sibi


2 Answers

From the Rust book:

Deref coercion is a convenience that Rust performs on arguments to functions and methods. Deref coercion converts a reference to a type that implements Deref into a reference to a type that Deref can convert the original type into. Deref coercion happens automatically when we pass a reference to a particular type’s value as an argument to a function or method that doesn’t match the parameter type in the function or method definition. A sequence of calls to the deref method converts the type we provided into the type the parameter needs.

So basically, in function arguments the compiler will automatically remove any & written or implied until it gets to a type that can be passed to the function.

like image 121
Jmb Avatar answered Feb 07 '23 17:02

Jmb


Because the compiler automatically dereferences the chain of references, you can imagine that it inserts as many * as necessary to get the right type:

foo(&&&f)

is converted to:

foo(&****(&&&f))

that leads to the right invocation:

foo(f)

The insertions of as many * as needed is actually performed by this blanket implementation of Deref trait:

impl<'a, T: ?Sized> Deref for &'a T {
    type Target = T;

    fn deref(&self) -> &T { *self }
}

Note: I've update my answer because in the original I used the term autoderef in the wrong way, see this post for details.

like image 45
attdona Avatar answered Feb 07 '23 18:02

attdona