- 질문 게시판입니다.
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
감사합니다. 확인해 보겠습니다.
목록
번호 제목 이름 날짜 조회 추천
공지 질문 게시판 이용 규정 11 토비 15/06/19 24501 4
16680 기타차량 폐차 관련 질문입니다. 23 + 메존일각 25/04/17 177 0
16679 법률부동산 복비 관련 문의드립니다. 2 [익명] 25/04/17 146 0
16678 IT/컴퓨터24인치 듀얼 모니터 vs 27인치 울트라와이드모니터1대 9 Picard 25/04/17 237 0
16677 체육/스포츠첫 런닝 관련 초보 질문 사항 4 아재 25/04/16 239 0
16676 기타차단기 문제 7 왕킹멍 25/04/15 300 0
16675 체육/스포츠초 6 여아 극기체험용 등산가방추천부탁드립니다. 6 FTHR컨설팅 25/04/15 294 0
16674 의료/건강왼쪽 오른쪽 시력차이가 엄청 크네요 5 OneV 25/04/15 362 0
16672 기타소형차 중고 가격및 유지비 질문드립니다 8 셀레네 25/04/14 329 0
16671 IT/컴퓨터중국산 로봇청소기 사생활 위험 어떻게 보시나요 8 당근매니아 25/04/14 453 0
16670 가정/육아매트리스 추천을 부탁드립니다 :) 10 Broccoli 25/04/14 268 0
16669 법률양도세 계산 관련하여 질문 있습니다. 8 [익명] 25/04/14 315 0
16668 기타서울 남쪽에 아버지 모시고 식사할 곳 찾는 중입니다. 4 퍼그 25/04/14 287 0
16667 기타인터넷 질문입니다 5 김치찌개 25/04/14 219 0
16666 의료/건강건강보험 3자행위 신고 질문입니다. 2 [익명] 25/04/13 369 0
16665 기타1500 이하로 살 수 있는 중고 suv 추천해주십시오 11 개백정 25/04/13 648 0
16664 IT/컴퓨터컴퓨터 정리 프로그램 추천부탁드립니다. 홍차넷 선생님들!! 13 Mandarin 25/04/11 527 0
16663 기타일본여행 항공권 선택장애 질문드립니다 28 쉬군 25/04/10 662 0
16662 법률내용증명 보내는데 주소를 몰라요! 8 유니브로 25/04/10 624 0
16661 체육/스포츠튼튼한 수영복 브랜드 무엇이 좋나요? 16 열한시육분 25/04/10 536 0
16660 기타리클라이너 의자 추천 18 노는꿀벌 25/04/10 508 0
16659 의료/건강신경과? 신경외과? 어디 가야 할까요? 2 키위 25/04/10 441 0
16658 의료/건강신체에 왼편만 불편함을 느끼고 있습니다 어떤 병원을 가야하나요? 5 [익명] 25/04/09 557 0
16657 IT/컴퓨터맥북이 갑지기 먹통이되었습니다 3 FTHR컨설팅 25/04/08 290 0
16656 게임디비전류 게임 추천해주십시오 4 린디합도그 25/04/08 277 0
목록

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

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