- 질문 게시판입니다.
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
감사합니다. 확인해 보겠습니다.
목록
번호 제목 이름 날짜 조회 추천
15805 IT/컴퓨터usb 포트 늘리는 물건 추천해주실수 있을까요? 6 kaestro 24/04/28 1736 0
15799 IT/컴퓨터크롬캐스트4세대로 넷플릭스 광고요금제 볼수 있나요? 일리지 24/04/26 1185 0
15796 IT/컴퓨터가계부앱 질문 1 whenyouinRome... 24/04/25 1506 0
15783 IT/컴퓨터데스크탑 견적 좀 봐주시오... 21 설탕 24/04/19 2070 0
15774 IT/컴퓨터Rust 프로그래밍: constructor 내부 closure에서 Self의 객체를 불러서 처리하기 6 T.Robin 24/04/17 1711 0
15771 IT/컴퓨터요즘은 타자 연습 뭘로 할까요? 11 토비 24/04/16 1813 0
15770 IT/컴퓨터모바일에서 보기 편한 스프레드시트? 4 메존일각 24/04/16 1691 0
15761 IT/컴퓨터제가 운영하는 웹사이트에 error_log 파일이 쌓이고 있는데 도움부탁드립니다. 4 스톤위키 24/04/13 2017 0
15757 IT/컴퓨터TV로 파일 영상을 잘 보려면? 1 2024 24/04/11 1486 0
15755 IT/컴퓨터알뜰폰 쓰는 사람이 해외여행갈때 어떻게 하면 좋을지요? 6 Broccoli 24/04/11 2395 0
15752 IT/컴퓨터안드로이드 TV에서 DVD 파일 재생 4 OshiN 24/04/08 1976 0
15740 IT/컴퓨터크롬에서 똑같은 파일 다운로드가 2개씩 됩니다. 4 메존일각 24/04/02 1876 0
15734 IT/컴퓨터[엑셀활용] 자료수합 관련하여 조언 필요합니다. 3 HeatWade 24/03/31 1642 0
15732 IT/컴퓨터aside를 왼쪽으로 이동시키고 싶습니다 4 kaestro 24/03/31 1957 0
15731 IT/컴퓨터오래된 노트북 수리를 어떻게 하면 좋을까요? 2 목화씨 24/03/30 1806 0
15726 IT/컴퓨터클리앙 난민들은 보시오 31 헬리제의우울 24/03/28 3667 2
15720 IT/컴퓨터카카오톡에서 엑셀 붙여넣을때? 13 매뉴물있뉴 24/03/25 3936 0
15706 IT/컴퓨터사설에서 아이폰 배터리 교체시에 암호를… 3 마우스노동러 24/03/19 2701 0
15700 IT/컴퓨터인터넷 속도가 잘안나오는데 공유기 바꾸면 괜찮을까요? 13 swear 24/03/18 1979 0
15698 IT/컴퓨터이 중고 모니터+본체 얼마정도 예상해야 할까요? 4 카르스 24/03/18 1261 0
15695 IT/컴퓨터중고컴퓨터 가성비 끝판왕을 찾읍니다. 18 dolmusa 24/03/15 2168 0
15694 IT/컴퓨터모바일 크롬 영상 재생시 세로로 꽉찬 화면 2 방사능홍차 24/03/14 2052 0
15684 IT/컴퓨터크롬 초기화 후 PC에 접속하면 로그인이 계속 풀려있습니다. 1 swear 24/03/10 1796 0
15674 IT/컴퓨터카플레이 모니터에서 발생하는 잡음 5 매뉴물있뉴 24/03/04 2424 0
15665 IT/컴퓨터노트북 사양 문의드립니다. 2 곰곰이 24/02/28 1897 0
목록

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

댓글
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기
회원정보 보기
닫기