简体   繁体   中英

How to destructure tuple struct with reference

I'm trying to use the hyper library to make some requests. The Headers::get() method returns Option<&H> , where H is a tuple struct with one field. I can use if let Some() to destructure the Option . But how do we destructure the &H ? Sure I could always access the field with .0 , but I'm curious if Rust has a syntax to do this.

struct s(String);

fn f(input: &s) -> &s {
    input
}

fn main() {
    let my_struct1 = s("a".to_owned());
    let s(foo) = my_struct1;
    let my_struct2 = s("b".to_owned());
    let &s(bar) = f(&my_struct2); // this does not work
    let baz = &my_struct2.0; // this works
}

When you try to compile this, the Rust compiler will tell you how to fix the error with a nice message:

error[E0507]: cannot move out of borrowed content
  --> <anon>:11:9
   |
11 |     let &s(bar) = f(&my_struct2); // this does not work
   |         ^^^---^
   |         |  |
   |         |  hint: to prevent move, use `ref bar` or `ref mut bar`
   |         cannot move out of borrowed content

This is needed to tell the compiler that you only want a reference to the field in the struct; the default matching will perform a move and the original struct value will no longer be valid.

Let's fix the example:

struct s(String);

fn f(input: &s) -> &s {
    input
}

fn main() {
    let my_struct1 = s("a".to_owned());
    let s(foo) = my_struct1;
    let my_struct2 = s("b".to_owned());
    let &s(ref bar) = f(&my_struct2);
}

Another way is to dereference first and drop the & . I think this is preferred in Rust:

struct s(String);

fn f(input: &s) -> &s {
    input
}

fn main() {
    let my_struct1 = s("a".to_owned());
    let s(foo) = my_struct1;
    let my_struct2 = s("b".to_owned());
    let s(ref bar) = *f(&my_struct2);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM