2017-01-21 8 views
0

Я пытаюсь написать простую функцию prompt, которая возвращает строку ввода без возврата к символам новой строки, но я не могу вернуть результат, потому что input не проживает долго достаточно. Я понимаю, что String::trim_right_matches возвращает заимствованную ссылку на часть input: String, но я не могу понять, как взять на себя ответственность за эти данные или скопировать ее как-то, чтобы вернуть ее.Эффективно получить право собственности на заимствованную ссылку для возврата из функции

Я уже несколько часов крутил колеса в течение нескольких часов, но я узнал, что это «борьба с заемщиком» - это обряд для новичков в Rust, поэтому я думаю, что я не одинок ,

use std::io; 
use std::io::Write; 

fn main() { 
    println!("you entered: {}", prompt("enter some text: ")); 
} 

fn prompt(msg: &str) -> &str { 
    print!("{}", msg); 

    io::stdout().flush() 
     .ok() 
     .expect("could not flush stdout"); 

    let mut input = String::new(); 

    io::stdin() 
     .read_line(&mut input) 
     .expect("failed to read from stdin"); 

    input.trim_right_matches(|c| c == '\r' || c == '\n') 
} 

Интуиция подсказывает мне, что нужно иметь fn prompt(prompt: &str) -> str вместо -> &str, но я не был в состоянии осуществить что таким образом компилятор принимает.

error: `input` does not live long enough 
    --> src/main.rs:22:5 
    | 
22 |  input.trim_right_matches(|c| c == '\r' || c == '\n').clone() 
    |  ^^^^^ does not live long enough 
23 | } 
    | - borrowed value only lives until here 
    | 
note: borrowed value must be valid for the anonymous lifetime #1 defined on the block at 9:32... 
    --> src/main.rs:9:33 
    | 
9 | fn prompt(msg: &str) -> &str { 
    |        ^

error: aborting due to previous error 
+1

Кажется, что это связано с [этим разделом документов] (https://doc.rust-lang.org/nomicon/lifetimes.html#example-references- что-переживет-референт). –

+0

Помогло ли downvoter предложить способы улучшить этот вопрос? –

ответ

2

Вы можете вернуть только &str если это срез ушедшей в аргументе, так что позволило бы ему иметь срок, равный аргументу. Ломтик локально выделенного String будет действителен только во время действия функции, поэтому вы не сможете его вернуть. Вам нужно будет вернуть (выехать) принадлежащее String

+0

Я буду признавать это как истину, но я до сих пор не понимаю: как это функционально отличается от передачи принадлежащей 'str'? Разве мой «ввод: Строка» не имеет привязки к телу функции? –

+1

Вы не можете иметь 'str' (кроме как в поле« »). 'str' - это фрагмент строки или констант. Он может существовать только как ссылка '& str'. С другой стороны, передавая аргумент 'String' *, он перемещает * его в функцию, что означает, что функция принадлежит ему. И то, что принадлежит, может быть снова перенесено. – the8472