Pattern matching in function signature

What happens when we use & symbol for both variable name and type.
Below is my struct Config

 pub struct Config<'a> {
       pub server_ip: &'a str,
       pub server_port: u16,
       pub log_file: Option<&'a str>,
  }

I initialized the struct and passed the reference to the start_server function, and used below syntax to take the parameter,
pub fn start_server(&config :&Config) -> io::Result<()>
But the compiler gave me the below error.

30 | pub fn start_server(&config :&Config) -> io::Result<()> {
   |                     ^------
   |                     ||
   |                     |data moved here
   |                     |move occurs because `config` has type `config::parser::Config<'_>`, which does not implement the `Copy` trait
   |                     help: consider removing the `&`: `config`

I thought the above syntax is to allow config variable to be used without * symbol, I want to understand what is use case of this syntax.

Removing & as per the compiler resolves the error.

It does allow this, but it does so by copying the value, and you don't have a #[derive(Copy)] on your struct.

In your case, you should probably just take it by value instead. Note also that you should almost certainly be using String instead of &str in your config struct.

pub struct Config {
    pub server_ip: String,
    pub server_port: u16,
    pub log_file: Option<String>,
}
pub fn start_server(config: Config) -> io::Result<()> {
    ...
}

You don't want <'a> on your structs unless you know what it means.

1 Like

What if I don't want to copy the strings and just pass references because that struct is going to grow in the future, I thought passing references would be better and that is why added <'a>

Is this the always case or it depends, where can I read more about this?

If you move by value as I suggested without an ampersand on either the name or type, then the strings will not be copied either.

As for the need of copy, then yes you can only use reference patterns with types that are Copy. The use of & on the argument name is an example of patterns in function parameters.

Okay, I understood my multiple mistakes, strings will be copied at the time of struct initialization only , when I use without & for calling function it will be moved/owned not copied,
my last question is, does reference pattern always copy data?

Yes, reference patterns are equivalent to dereferencing with *, so it will always copy the data behind the reference.

1 Like

Shouldn't it just move, instead of copying, I assume copying and moving are two different things, please correct me if I am wrong.

The value is not moved because the function takes a reference.

fn takes_int(&int: &i32) {
    println!("{}", int);
}

fn main() {
    let i = 10;
    takes_int(&i); // <-- notice the ampersand
}
1 Like

Oh, that means I was trying to take ownership of data from borrowed reference.
thanks

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.