- 질문 게시판입니다.
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
감사합니다. 확인해 보겠습니다.
목록
번호 제목 이름 날짜 조회 추천
15984 IT/컴퓨터워시타워 vs 일체형 8 은하꾸리 24/07/07 2156 0
15983 IT/컴퓨터크롬이 데이터를 너무 많이 잡아먹습니다. 4 whenyouinRome... 24/07/05 1820 0
15981 IT/컴퓨터스마트폰 유심칩 교체 ? 11 치즈케이크 24/07/04 1799 0
15978 IT/컴퓨터커뮤니티 사용을 줄이는 방법이 있을까요?? 20 데자뷰 24/07/03 2374 2
15976 IT/컴퓨터플립5 vs 6 8 Beemo 24/07/03 1521 0
15964 IT/컴퓨터카메라에 입문했는데,,, 절대 크롭센서는 사면 안되는 건가요...? 16 도리돌이 24/06/28 1892 0
15940 IT/컴퓨터요즘에 새 휴대폰 살려면 어디로 가야 하나요?(갤럭시 S24 계열) 13 호에로펜 24/06/18 1794 0
15935 IT/컴퓨터QHD 27인치 vs 32인치 모니터 9 방사능홍차 24/06/17 1972 0
15920 IT/컴퓨터유튜브 자막 효과 질문 13 푸르던 24/06/11 1568 0
15910 IT/컴퓨터하드 용량이 이상한 거 같아요. 4 moqq 24/06/07 1800 0
15893 IT/컴퓨터갤럭시 z플립 로지텍 블루투스키보드 연결지연 3 다람쥐 24/05/27 1612 0
15890 IT/컴퓨터공업용선풍기 구동 커패시터 관련해 질문 드립니다. 1 전화위복어 24/05/27 1536 0
15885 IT/컴퓨터아이패드 애플케어플러스에 대해. 3 야얌 24/05/24 1497 0
15875 IT/컴퓨터Win 11 랩탑 로그인 문제 6 치즈케이크 24/05/22 1442 0
15874 IT/컴퓨터회사 노트북과 가정 PC 파일 공유 5 [익명] 24/05/22 1445 0
15858 IT/컴퓨터유튜브는 재생하면 기본 1080p 인데 4k 동영상 업로드가 의미가 있나요 6 루키루키 24/05/15 1794 0
15854 IT/컴퓨터소프트웨어 개발시 지분 관계 28 먹이 24/05/14 1673 0
15847 IT/컴퓨터ERP 솔루션 추천 부탁드립니다^^ 2 루키루키 24/05/13 1610 0
15833 IT/컴퓨터어도비 애크로뱃에서 갑자기 글씨가 이상하게 보입니다. 2 자공진 24/05/08 1469 0
15825 IT/컴퓨터통신사 무제한 데이터, 데이터 쉐어링 잘 아시는분... 7 dongri 24/05/04 2890 0
15821 IT/컴퓨터IT 계열에서 과제 테스트 일정이 잡혔습니다. 14 [익명] 24/05/03 1828 0
15820 IT/컴퓨터마라톤 대회용 카메라를 추천받고 싶습니다. 10 오디너리안 24/05/02 2294 0
15818 IT/컴퓨터네이버블로그/네이버카페/인스타그램/페이스북/링크드인 모와보기? 4 루키루키 24/05/02 1545 0
15814 IT/컴퓨터챗gpt같은 걸 써보고 싶은데, 추천부탁드립니다. 12 똘빼 24/04/29 2046 0
15811 IT/컴퓨터중고 크롬북을 사고 싶은데 마땅한 이유가 없읍니다 14 아침커피 24/04/29 1685 0
목록

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

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