2017-01-21 1 views
0

J'essaie d'écrire une fonction simple prompt qui retourne une chaîne d'entrée sans retour à la ligne, mais je ne suis pas capable de retourner mon résultat car input ne vit pas longtemps assez. Je comprends que String::trim_right_matches renvoie une référence empruntée à une partie de input: String, mais je ne peux pas comprendre comment prendre possession de ces données ou le copier d'une manière ou d'une autre pour le renvoyer. Je fais tourner mes roues depuis quelques heures maintenant sans aucune chance, bien que j'ai appris que «se battre avec le vérificateur d'emprunt» est un rite de passage pour les nouveaux arrivants à Rust, donc je suppose que je ne suis pas seul .Prendre en charge une référence empruntée pour retourner à partir d'une fonction

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') 
} 

Intuition me dit que je dois avoir fn prompt(prompt: &str) -> str au lieu de -> &str, mais je ne l'ai pas été en mesure d'effectuer cette manière le compilateur accepte.

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

Semble être lié à [cette section des docs] (https://doc.rust-lang.org/nomicon/lifetimes.html#example-references- that-outlive-referents). –

+0

Est-ce que le downvoter se souciait de suggérer des façons d'améliorer cette question? –

Répondre

2

Vous ne pouvez retourner un &str si elle est une tranche de l'argument passé dans car cela lui permettra d'avoir une durée de vie égale à l'argument. Une tranche de String affectée localement ne sera valide que pendant la durée de la fonction, vous ne pouvez donc pas la renvoyer. Vous devrez retourner un (e) propriétaire String

+0

Je vais accepter cela comme vérité, mais je ne comprends toujours pas: en quoi est-ce différent d'un point de vue fonctionnel que de passer un «str»? Mon 'input: String' n'a-t-il pas une durée de vie dans le corps de la fonction? –

+1

Vous ne pouvez pas posséder un 'str' (sauf dans un' Box '). 'str' est une tranche de' String' ou de constantes. Il ne peut exister que comme référence '& str'. Passer un 'String' comme argument d'un autre côté * le déplace * dans la fonction, ce qui signifie que la fonction le possède. Et ce qui est possédé peut aussi être retiré. – the8472