rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

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

Open cyqsimon opened this issue 2 years ago • 2 comments

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()
}

cyqsimon avatar Nov 04 '23 16:11 cyqsimon

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;
}

SOF3 avatar Nov 06 '23 04:11 SOF3

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

fmease avatar Feb 06 '24 19:02 fmease