Как я могу вернуть a

#rust

#Ржавчина

Вопрос:

Когда я пытаюсь запустить это:

 use std::thread::LocalKey;

struct Person {
    name: String,
}

impl Person {
    fn new(name: String) -> Self {
        Person {
            name: name,
        }
    }
    
    fn name(amp;self) -> amp;str {
        self.name.as_str()
    }
}

thread_local! {
    static NAMED_THING: Person = Person::new("John".to_string());
}

fn retrieve_name(p: amp;'static LocalKey<Person>) -> amp;str {
    p.with(|n| n.name())
}

fn main() {
    println!("The name is {}", retrieve_name(amp;NAMED_THING));
}
  

это говорит мне

 error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/main.rs:24:18
   |
24 |     p.with(|n| n.name())
   |                  ^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 24:12...
  --> src/main.rs:24:12
   |
24 |     p.with(|n| n.name())
   |            ^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:24:16
   |
24 |     p.with(|n| n.name())
   |                ^
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that reference does not outlive borrowed content
  

Я мог бы сделать вместо этого:

 fn retrieve_name(p: amp;'static LocalKey<Person>) -> amp;str {
    p.with(|n| n.name().to_owned().as_str())
}
  

Но каждый раз клонировать эту строку кажется довольно расточительным. Не говоря уже о том, что теперь он говорит мне:

 error[E0515]: cannot return value referencing temporary value
  --> src/main.rs:24:16
   |
24 |     p.with(|n| n.name().to_owned().as_str())
   |                -------------------^^^^^^^^^
   |                |
   |                returns a value referencing data owned by the current function
   |                temporary value created here
  

Игровая площадка

Ответ №1:

Вы не можете этого сделать.

Он Person будет уничтожен, когда поток завершится, и тогда любая ссылка на него (например, 'static ссылка, которая была отправлена в другой поток за это время) станет зависшей. Вот почему LocalKey имеет with метод вместо реализации Deref , как lazy_static это делают переменные: потому что использование 'static ссылки на локальное значение потока является необоснованным.

Вам нужно организовать свой код так, чтобы все заимствования ограничивались областью действия переданного замыкания with . Например:

 fn print_name(p: amp;'static LocalKey<Person>) {
    p.with(|n| println!("The name is {}", n.name()));
}

fn main() {
    print_name(amp;NAMED_THING);
}