That's not possible in Rust.
Unlike languages like Python, JavaScript, or C# where the foo.some_field
syntax can implicitly call a method to retrieve the field (often called a "property"), accessing a field in Rust is literally just some pointer arithmetic and (if accessing by value) a read through that pointer.
If you want to avoid writing |foo| foo.0
, you could use pattern matching to get something like this |(a, _)| a
.
Otherwise, if you really want to map tuples with a function, you'll need to write it yourself. This can be done using some const generics wizardry.
First, we introduce a TupleAccess
trait which acts as a fancy getter to read a field by index.
trait TupleAccess<const N: usize> {
type Value;
fn get(self) -> Self::Value;
}
Next, we can implement it for tuples of different arities (normally I'd use a macro_rules
macro here).
impl<A, B> TupleAccess<0> for (A, B) {
type Value = A;
fn get(self) -> A {
self.0
}
}
impl<A, B> TupleAccess<1> for (A, B) {
type Value = B;
fn get(self) -> B {
self.1
}
}
And finally, we can create functions that give our getters useful names.
fn first<T>(tuple: T) -> T::Value
where
T: TupleAccess<0>,
{
tuple.get()
}
fn second<T>(tuple: T) -> T::Value
where
T: TupleAccess<1>,
{
tuple.get()
}
In the end, this lets us access the tuple field with foo.map(first)
syntax.
fn main() {
let foo = Some((1, "Hello, World!"));
println!("First: {:?}", foo.map(first));
println!("Second: {:?}", foo.map(second));
}
(playground)
While it's a fun thought experiment, I wouldn't use this TupleAccess
trick in the real world.
It's just unnecessary cognitive load you are imposing on whoever reads the code, introducing more advanced concepts like traits with const generics and helper functions that you'll always need to remember, when previously people could just read a field access and continue with their day.