use chrono::Utc;
fn main() {
let current_timestamp: String = Utc::now().to_rfc3339();
let iter1 = vec![("time", ¤t_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.
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).