rust-lang / rfcs

RFCs for changes to Rust
https://rust-lang.github.io/rfcs/
Apache License 2.0
5.91k stars 1.57k forks source link

Add method or trait impl for converting reference of tuple to tuple of references #3520

Open cyqsimon opened 11 months ago

cyqsimon commented 11 months ago

Not sure what's the "formal" syntax to express "for tuples of any size", so I'll use 2-tuples here in my examples.

TL;DR, I want this:

let ref_of_tuple: &(u8, u16) = &(6, 9);
let tuple_of_refs: (&u8, &u16) = ref_of_tuple.as_ref();
assert_eq!(tuple_of_refs, (&6, &9));

Much like how Option::as_ref converts from &Option<T> to Option<&T>.


Besides being generally useful, it also allows for more readable code in some circumstances:

fn convert(from: &[(u8, u16)]) -> Vec<(&u8, &u16)> {
    from.iter()
        .map(|(a, b)| (a, b)) // huh?
        .collect()
}

It looks like the map isn't doing anything, but due to how destructuring works, it's actually necessary. This would be much clearer:

fn convert(from: &[(u8, u16)]) -> Vec<(&u8, &u16)> {
    from.iter()
        .map(AsRef::as_ref)
        .collect()
}
SOF3 commented 11 months ago

The generic API might have become more feasible since GAT is stable now:

pub trait Map {
    type Output<Input>;
    fn map<Input>(&self, input: Input) -> Self::Output<Input>;
}
impl tuple {
    pub fn map<M: Map>(self, m: &M) -> tuple;
}
fmease commented 8 months ago

This should probably be an ACP (API change proposal) over at https://github.com/rust-lang/libs-team/issues if fleshed out a bit.