- 질문 게시판입니다.
Date 24/04/17 15:48:38수정됨
Name   T.Robin
Subject   Rust 프로그래밍: constructor 내부 closure에서 Self의 객체를 불러서 처리하기
Rust 도전 일주일차인 T.Robin입니다(아 응애에요).
대충 아래의 코드가 있습니다.



struct S1 {
    element1: AAA,
    element2: BBB,
}

impl S1 {
    pub fn new()->Self {
        let result = Self { element1: Element1::new(), element2: Element2::new() }
        // 뭔가 이것저것......

        result.element1.do_something( {
            let element1_weak_reference = result.element1.get_weak_reference().unwrap();
            move || {
                // 여기가 문제
                result.element2.do_something_else( element1_weak_reference.do_something() );
            }
        });

        // 완료
        result
    }
}



아마 눈치채셨겠지만, 이 코드는 빌드되지 않습니다. [//여기가 문제] 부분에서 result.element2가 closure 안쪽으로 이동해버려서, 마지막 "[//완료]" 부분에서는 result.element2가 아직 변수를 빌려준 상태로 남아있게 되어서 컴파일러가 투덜댑니다(요컨데, closure가 본문보다 더 오래 살아남을 수 있다....... 뭐 이런 내용입니다).

아예 unsafe 선언하고 C++ 스타일 raw pointer로 막무가내로 밀어부쳐 보기도 했습니다만 프로그램이 터지는걸 보면 이것도 답은 아닌 것 같습니다.
이 경우, 어떻게 처리해야 될까요?



0


홍차넷 게시판은 코드를 게시하기에 참 좋지 아니합니다.
요즘 게시판들은 코드블럭 지원하는 것들도 많던데...
T.Robin
이 글 작성하면서 HTML 태그를 직접 건드릴까 생각해봤습니다만 그러기엔 너무 번거로워서.......
그르니에
전 아니고 chatGPT 4.0가 이렇게 추천하는군요

여기서 발생하는 문제는 `result`라는 변수의 소유권이 `do_something` 클로저 내부로 이동하려고 하기 때문입니다. 러스트에서는 하나의 변수에 대한 소유권을 다른 스코프로 이동할 수 없으며, 이런 이동이 발생하려고 하면 컴파일 에러가 발생합니다. 여기서는 `result`가 이 함수의 마지막에서 반환되어야 하기 때문에 클로저 내부에서 이 변수를 직접 사용하는 것은 불가능합니다.

문제를 해결하기 위해 몇 가지 접근 방식을 사용할 수 있습니다:

1. **클... 더 보기
전 아니고 chatGPT 4.0가 이렇게 추천하는군요

여기서 발생하는 문제는 `result`라는 변수의 소유권이 `do_something` 클로저 내부로 이동하려고 하기 때문입니다. 러스트에서는 하나의 변수에 대한 소유권을 다른 스코프로 이동할 수 없으며, 이런 이동이 발생하려고 하면 컴파일 에러가 발생합니다. 여기서는 `result`가 이 함수의 마지막에서 반환되어야 하기 때문에 클로저 내부에서 이 변수를 직접 사용하는 것은 불가능합니다.

문제를 해결하기 위해 몇 가지 접근 방식을 사용할 수 있습니다:

1. **클로저 내부에서 `result`의 특정 필드에만 접근하고, 전체 구조체를 클로저 안으로 이동하지 않도록 합니다.** 이를 위해 `element2`를 별도의 변수로 분리하고 이를 클로저로 이동할 수 있습니다. 그러나 이 경우 `element1`과 `element2` 간의 상호작용을 클로저 안에서 처리하기 어려울 수 있습니다.

2. **Arc와 Mutex 또는 RwLock을 사용하여 `element1`과 `element2`를 공유합니다.** 이 방법은 멀티 스레드 환경에서도 안전하게 요소들을 공유할 수 있게 합니다. 클로저에서는 `Arc<Mutex<_>>` 또는 `Arc<RwLock<_>>`를 통해 각 요소에 접근할 수 있습니다.

다음은 `Arc`와 `Mutex`를 사용한 예시 코드입니다:

```rust
use std::sync::~{Arc, Mutex};

struct Element1 ~{
// element1의 필드들
}

impl Element1 ~{
fn new() -> Self ~{
Self ~{ /* 초기화 */ }
}

fn get_weak_reference(&self) -> Option<Arc<Mutex<Self>>> ~{
Some(Arc::new(Mutex::new(Self ~{ /* 초기화 */ })))
}

fn do_something(&self) ~{
// element1의 동작
}
}

struct Element2 ~{
// element2의 필드들
}

impl Element2 ~{
fn new() -> Self ~{
Self ~{ /* 초기화 */ }
}

fn do_something_else(&self, _: ()) ~{
// element2의 동작
}
}

struct S1 ~{
element1: Arc<Mutex<Element1>>,
element2: Arc<Mutex<Element2>>,
}

impl S1 ~{
pub fn new() -> Self ~{
let element1 = Arc::new(Mutex::new(Element1::new()));
let element2 = Arc::new(Mutex::new(Element2::new()));

let element1_clone = Arc::clone(&element1);
let element2_clone = Arc::clone(&element2);

let result = Self ~{
element1,
element2,
};

// Mutex로 감싸진 element1의 약한 참조를 얻음
if let Some(element1_weak_reference) = element1_clone.lock().unwrap().get_weak_reference() ~{
let element2_weak = element2_clone;
element1_clone.lock().unwrap().do_something(~{
move || ~{
// 여기서 element2의 Mutex를 잠그고 함수를 호출
element2_weak.lock().unwrap().do_something_else(element1_weak_reference.lock().unwrap().do_something());
}
});
}

result
}
}

fn main() ~{
let s = S1::new();
}
```

위 코드에서는 `Element1`과 `Element2`를 `Arc<Mutex<_>>`로 감싸서 클로저 안에서 안전하게 사용할 수 있도록 합니다. 클로저는 `element2`의 `Mutex`를 잠근 후 `do_something_else`를 호출합니다. 이렇게 하면 소유권 문제를 회피하면서도 동시성을 유지할 수 있습니다.
1
두번우려낸티백
휴먼지능으로도 이게 맞습니다
확인 감사합니다.
Rust는 뭐랄까...... 쓸데없이 손이 번거로워진다는 느낌이군요. 머릿속에 RTTI 다 보이는데 꼭 이렇게까지 번거롭게 해야 되나.......
T.Robin
감사합니다. 확인해 보겠습니다.
목록
번호 제목 이름 날짜 조회 추천
15811 IT/컴퓨터중고 크롬북을 사고 싶은데 마땅한 이유가 없읍니다 14 아침커피 24/04/29 1991 0
15806 IT/컴퓨터5만원 미만 스마트워치? 10 기아트윈스 24/04/28 1933 0
15805 IT/컴퓨터usb 포트 늘리는 물건 추천해주실수 있을까요? 6 kaestro 24/04/28 2165 0
15799 IT/컴퓨터크롬캐스트4세대로 넷플릭스 광고요금제 볼수 있나요? 일리지 24/04/26 1489 0
15796 IT/컴퓨터가계부앱 질문 1 whenyouinRome... 24/04/25 1845 0
15783 IT/컴퓨터데스크탑 견적 좀 봐주시오... 21 설탕 24/04/19 2422 0
15774 IT/컴퓨터Rust 프로그래밍: constructor 내부 closure에서 Self의 객체를 불러서 처리하기 6 T.Robin 24/04/17 2072 0
15771 IT/컴퓨터요즘은 타자 연습 뭘로 할까요? 11 토비 24/04/16 2104 0
15770 IT/컴퓨터모바일에서 보기 편한 스프레드시트? 4 메존일각 24/04/16 1981 0
15761 IT/컴퓨터제가 운영하는 웹사이트에 error_log 파일이 쌓이고 있는데 도움부탁드립니다. 4 스톤위키(FTHR컨설팅) 24/04/13 2353 0
15757 IT/컴퓨터TV로 파일 영상을 잘 보려면? 1 2024 24/04/11 1797 0
15755 IT/컴퓨터알뜰폰 쓰는 사람이 해외여행갈때 어떻게 하면 좋을지요? 6 Broccoli 24/04/11 2845 0
15752 IT/컴퓨터안드로이드 TV에서 DVD 파일 재생 4 OshiN 24/04/08 2338 0
15740 IT/컴퓨터크롬에서 똑같은 파일 다운로드가 2개씩 됩니다. 4 메존일각 24/04/02 2248 0
15734 IT/컴퓨터[엑셀활용] 자료수합 관련하여 조언 필요합니다. 3 HeatWade 24/03/31 1924 0
15732 IT/컴퓨터aside를 왼쪽으로 이동시키고 싶습니다 4 kaestro 24/03/31 2281 0
15731 IT/컴퓨터오래된 노트북 수리를 어떻게 하면 좋을까요? 2 목화씨 24/03/30 2104 0
15726 IT/컴퓨터클리앙 난민들은 보시오 31 헬리제의우울 24/03/28 4024 2
15720 IT/컴퓨터카카오톡에서 엑셀 붙여넣을때? 13 매뉴물있뉴 24/03/25 5536 0
15706 IT/컴퓨터사설에서 아이폰 배터리 교체시에 암호를… 3 마우스노동러 24/03/19 4401 0
15700 IT/컴퓨터인터넷 속도가 잘안나오는데 공유기 바꾸면 괜찮을까요? 13 swear 24/03/18 2401 0
15698 IT/컴퓨터이 중고 모니터+본체 얼마정도 예상해야 할까요? 4 카르스 24/03/18 1575 0
15695 IT/컴퓨터중고컴퓨터 가성비 끝판왕을 찾읍니다. 18 dolmusa 24/03/15 2510 0
15694 IT/컴퓨터모바일 크롬 영상 재생시 세로로 꽉찬 화면 2 방사능홍차 24/03/14 2530 0
15684 IT/컴퓨터크롬 초기화 후 PC에 접속하면 로그인이 계속 풀려있습니다. 1 swear 24/03/10 2157 0
목록

+ : 최근 2시간내에 달린 댓글
+ : 최근 4시간내에 달린 댓글

댓글