구조체 메서드 : 불변으로 빌려 오기 때문에 가변으로 빌릴 수 없습니다.

Sep 26 2020

차용 검사기를 만족시킬 수없는 다음 코드 (예제)가 있습니다. 한 메서드는의 한 필드 struct를 수정하고 다른 메서드를 호출하여 다른 메서드를 수정합니다. 문제는 두 번째 메서드를 호출 할 때 구조체에 의존하는 매개 변수가 필요하다는 것입니다. second메서드 호출 은 인수 &self.a와 함께 작동하지 않으며 &mut self.a두 번째 변경 가능한 차용이기 때문에 둘 다 작동하지 않습니다 .

결국 나는 하나의 방법으로 모든 코드를 가지고 그것을 고쳤지만 (실제 문제에서) 지옥처럼 못 생겼습니다. 이 문제를 어떻게 해결할 수 있습니까? (매개 변수 &self.a가 필요하지 않다는 것을 알고 있지만 설명하고 싶은 요점은 아닙니다 ...)


struct ABC {
    a: Vec<i32>,    // no Copy trait
    b: i32,
}

impl ABC {
    fn new() -> ABC { ABC {a: vec![0,1], b: 10} }

    fn first(&mut self) {
        self.a.push(2);         // updates one field
        self.second(&self.a);   // uses a method to update the other field
    }

    fn second(&mut self, x: &Vec<i32>) {
        self.b += x[1];
    }
}

fn main() {
    let mut s = ABC::new();
    s.first();
}

여기에 놀이터 .

답변

2 edkeveked Sep 26 2020 at 02:23

당신은 이미 자기에게서 빌 렸습니다. 차용이있는 한 두 번째 방법으로 이동할 수 없습니다. to_vec()데이터를 두 번째 방법으로 복사하는 데 사용할 수 있습니다 .

struct ABC {
    a: Vec<i32>,    // no Copy trait
    b: i32,
}

impl ABC {
    fn new() -> ABC { ABC {a: vec![0,1], b: 10} }

    fn first(&mut self) {
        self.a.push(2);         // updates one field
        self.second(self.a.to_vec());
    }

    fn second(&mut self, x: Vec<i32>) {
        self.b += x[1];
    }
}

fn main() {
    let mut s = ABC::new();
    s.first();
}

운동장

그러나 표시된대로 데이터를 복사합니다.

가장 간단한 방법 self.b은 first메서드 에서 업데이트 하는 것입니다. 그런 식으로 우리는self.a

    fn first(&mut self) {
        self.a.push(2);         // updates one field
        self.b += self.a[1];
    }

second가에서 빌리지 않으면 self다음과 같이 작동합니다.

struct ABC {
    a: Vec<i32>, // no Copy trait
    b: i32,
}

impl ABC {
    fn new() -> ABC {
        ABC {
            a: vec![0, 1],
            b: 10,
        }
    }

    fn first(&mut self) {
        self.a.push(2); // updates one field
        Self::second(&mut self.b, &self.a);
    }
    fn second(y: &mut i32, x: &Vec<i32>) {
        *y += x[1];
    }
}

fn main() {
    let mut s = ABC::new();
    s.first();
}

그러나 방법 에서 self.b직접 업데이트하는 것과 크게 다르지 않습니다 first.