What's a &String and how do I convert it into a &str?

In this code:

use chrono::Utc;

fn main() {
    let current_timestamp: String = Utc::now().to_rfc3339();
    let iter1 = vec![("time", &current_timestamp].iter();
    let fields = iter1.chain(vec![("foo", "bar")].iter());
    let v: Vec<(&str, &str)> = fields.collect();
    println!("{}", v.len());
}

I somehow ended up with a &String:

error[E0271]: type mismatch resolving `<Iter<'_, (&str, &str)> as IntoIterator>::Item == &(&str, &String)`
 --> src/main.rs:6:30
  |
6 |     let fields = iter1.chain(vec![("foo", "bar")].iter());
  |                        ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `str`
  |                        |
  |                        required by a bound introduced by this call
  |
  = note: expected reference `&(&str, &String)`
             found reference `&(&str, &str)`
note: the method call chain might not have had the expected associated types

I have never seen such a thing and of course I intended to get a &str.

Playground

It isn't anything special. String is simply and literally a reference to a value of type String. The address-of operator, &, takes a reference to its argument. If the argument has type String, then a reference to it has type &String. What's wrong with that?

If you want a &str out of it, you can use a deref coercion or be explicit and call .as_str() or .as_ref().

There is one more problem with your code – you are calling .iter() which gives you references to the items of the vector (in this case, a reference to a tuple), but you want to collect into a Vec that has the original item type (ie., not reference-to-tuple, just tuple). That doesn't compile — you want .into_iter() instead.

(also note how the argument of chain doesn't need to be an iterator, merely an iterable, ie. you can pass the collection itself.)

If you refer to this diagram, a String corresponds to a Vec<u8> and a &str corresponds to a &[u8] (with additional requirements on the contained bytes being UTF8). A &String would be a reference to the String (like &T in the diagram).

[1]


  1. The diagram is a bit dated as Mutex no longer allocates on most or all platforms, but the rest is accurate. ↩ī¸Ž

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.