2014-11-14 8 views
3

구조체 함수가 특별한 조건 하에서 스스로를 호출하기를 원합니다. 필드의 하나로서 HashMap이있을 때 작동했지만, 을 Vec으로 변경했을 때 깨졌습니다. 그것은 심지어 사용 되어질 필요가 없으며, 매우 이상하게 보이고 이에 대한 합당한 설명을 찾을 수 없습니다.은`* self`을 변경할 수 없기 때문에 빌릴 수 없습니다.

use std::vec::Vec; 
use std::collections::HashMap; 

struct Foo<'a> { 
    bar: Vec<&'a str> 
    //bar: HashMap<&'a str, &'a str> 
} 

impl<'a> Foo<'a> { 
    pub fn new() -> Foo<'a> { 
     Foo { bar: Vec::new() } 
     //Foo { bar: HashMap::new() } 
    } 

    pub fn baz(&'a self) -> Option<int> { 
     None 
    } 

    pub fn qux(&'a mut self, retry: bool) { 
     let opt = self.baz(); 
     if retry { self.qux(false); } 
    } 
} 

pub fn main() { 
    let mut foo = Foo::new(); 
    foo.qux(true); 
} 

놀이 틀 : http://is.gd/GgMy79

오류 :

나는이 문제를 해결할 수있는 방법
<anon>:22:24: 22:28 error: cannot borrow `*self` as mutable because it is also borrowed as immutable 
<anon>:22    if retry { self.qux(false); } 
           ^~~~ 
<anon>:21:23: 21:27 note: previous borrow of `*self` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `*self` until the borrow ends 
<anon>:21    let opt = self.baz(); 
           ^~~~ 
<anon>:23:10: 23:10 note: previous borrow ends here 
<anon>:20   pub fn qux(&'a mut self, retry: bool) { 
<anon>:21    let opt = self.baz(); 
<anon>:22    if retry { self.qux(false); } 
<anon>:23   } 

? 이 원인이 #6268일까요?

+0

방법'바즈의 정의()'에서'A'를 제거 제출했다. 왜 그것이 그것을 일으키는 지 모르겠다. – Levans

답변

3

이유를 찾았습니다. 이 HashMap 정의입니다 :

pub struct Vec<T> { 
    ptr: *mut T, 
    len: uint, 
    cap: uint, 
} 

유일한 차이는 유형 매개 변수를 사용하는 방법은 다음과 같습니다

pub struct HashMap<K, V, H = RandomSipHasher> { 
    // All hashes are keyed on these values, to prevent hash collision attacks. 
    hasher: H, 

    table: RawTable<K, V>, 

    // We keep this at the end since it might as well have tail padding. 
    resize_policy: DefaultResizePolicy, 
} 

Vec 정의입니다. 이제이 코드를 확인하자 :

struct S1<T> { s: Option<T> } 
//struct S1<T> { s: *mut T } 

struct Foo<'a> { 
    bar: S1<&'a str> 
} 

impl<'a> Foo<'a> { 
    pub fn new() -> Foo<'a> { // ' 
     Foo { bar: S1 { s: None } } 
     //Foo { bar: S1 { s: std::ptr::null_mut() } } 
    } 

    pub fn baz(&'a self) -> Option<int> { 
     None 
    } 

    pub fn qux(&'a mut self, retry: bool) { 
     let opt = self.baz(); 
     if retry { self.qux(false); } 
    } 
} 

pub fn main() { 
    let mut foo = Foo::new(); 
    foo.qux(true); 
} 

이 하나가 컴파일합니다. S1에 대한 다른 정의를 *mut T 포인터로 선택하면이 오류로 프로그램이 실패합니다.

이것은 평생 변이의 어딘가에있는 버그처럼 보입니다.

업데이트here

+0

굉장, 고마워. :) – jgillich

관련 문제