2014-11-21 1 views
1

파일을 열고 일부 문자를 바꿔서 일부 나누기를하고 싶습니다. 그런 다음 문자열 목록을 반환하고 싶습니다. 그러나 나는 error: broken does not live long enough을 얻는다. 내 코드는 메인에있을 때 작동하므로 수명에만 문제가됩니다.수명이 오래 오래 녹지 않았습니다.

fn tokenize<'r>(fp: &'r str) -> Vec<&'r str> { 
    let data = match File::open(&Path::new(fp)).read_to_string(){ 
     Ok(n) => n, 
     Err(e) => fail!("couldn't read file: {}", e.desc) 
    }; 
    let broken = data.replace("'", " ' ").replace("\"", " \" ").replace(" ", " "); 
    let mut tokens = vec![]; 

    for t in broken.as_slice().split_str(" ").filter(|&x| *x != "\n"){ 
     tokens.push(t) 
    } 
    return tokens; 
} 

어떻게이 함수가 반환 한 값을 호출자의 범위에 포함시킬 수 있습니까?

답변

3

문제는 기능 서명이 "결과가 입력 fp과 동일한 수명을가집니다"라고하지만 실제로는 그렇지 않습니다. 결과에는 함수 내에 할당 된 data에 대한 참조가 포함됩니다. 그것은 fp와 아무런 관련이 없습니다! 그대로 서면 data은 기능이 끝날 때 중단됩니다.

새로운 값을 효과적으로 생성하기 때문에 참조를 반환 할 수 없습니다. 함수에서 해당 데이터의 소유권을 이전해야합니다.

대신 Vec<&str>를 반환
  1. Vec<String>를 반환, 각 토큰은 새로 할당 된 문자열입니다 : 내 머리 위로 떨어져,이 작업을 수행하는 내가 생각할 수있는 두 가지 방법이 있습니다.

  2. 돌아 가기 data은 분할 논리를 구현하는 래퍼 유형 내에 있습니다. 그런 다음 fn get_tokens(&self) -> Vec<&str>을 가질 수 있습니다. 슬라이스의 수명은 data을 포함하는 객체의 수명에 연결될 수 있습니다.

+0

String으로 변환하면 수명이 증가하는 이유는 무엇입니까? 그들은 컨테이너 소유입니까? – ragingSloth

+0

꽤 많이 있습니다. 'Vec'과'String'은 컨테이너를 소유하고 있습니다. 주변 사람들 중 하나를 지나칠 때 실제로 가치를 유지하기 위해 할당 된 메모리의 소유권을 이전합니다. '& str'은 단순히 빌려준 * reference입니다; 그것은 빌린 물건만큼 오래 살 수 있습니다. –