Hacker News new | ask | show | jobs
by nextaccountic 1645 days ago
If you have a String, passing a &str is free, you just.. put a & before your string. that's because if you expect a &str and pass a &String, the &String auto-derefs to &str. This is called a deref coercion[0]

Like, if you have fn f(s: &str), you can do:

    let x: String = String::from(something);
    f(&x);
You can see this in playground here [1] (click "Run")

To explain: both String and &str is essentially a pointer plus metadata, but &String is a double pointer (a pointer to a pointer). Rust knows how to convert double pointers to pointers, using the Deref trait. This implicit conversion is applied only in a handful of places, and only if it doesn't lead to any ambiguity (if f received a generic parameter it wouldn't work for example).

If you wanted to convert String to &str explictly, you would need to write &*x, like this (see in the playground here [2]):

    let x: String = String::from(something);
    f(&*x);
That's because if x has type String, *x has type str (because String impls Deref<Target = str> [3]) and &*x has type &str. This means that auto-deref changed your &x into &*x automatically.

[0] https://doc.rust-lang.org/book/ch15-02-deref.html#implicit-d...

[1] https://play.rust-lang.org/?version=stable&mode=debug&editio...

[2] https://play.rust-lang.org/?version=stable&mode=debug&editio...*

[3] https://doc.rust-lang.org/alloc/string/struct.String.html#im...