C.W.K.
Stream
Lesson 04 of 05 · published

함수 호출을 넘나드는 소유권

~11 min · ownership, functions, move, return

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

소유권 규칙은 let 에서 멈추지 않아. 함수에 값을 넘기는 것도 할당이랑 똑같이 move 해 — 그리고 그건 borrowing 으로 고치기 전에 똑똑히 봐둘 가치가 있는 결과를 낳아.

넘기면 move (또는 복사)

String 으로 takes(s) 를 호출하면 소유권이 함수 안으로 move 해. 호출 후엔 호출자가 더는 s 를 소유 안 하고 못 써. 인자가 i32 같은 Copy 타입이면 대신 복사돼서 호출자가 값을 유지해 — 할당이랑 같은 규칙이야.

반환이 소유권을 돌려줘

함수는 반환값으로 소유권을 돌려줄 수 있어. 그래서 전형적인 (투박한) 패턴은: 값을 받고, 쓰고, 호출자가 다시 갖게 반환하는 거야. 되긴 하지만 함수마다 소유권을 손으로 넣고 빼는 건 지쳐 — 읽기만 하고 싶었던 값을 유지하려고 튜플을 반환하는 걸 상상해봐.

이 레슨은 borrowing 을 위한 빌드업이야. 값을 함수에 move 했다가 유지하려고 반환하는 게 너무 지겨워서 Rust 는 더 나은 도구를 줘: 참조. 다음 트랙이 보상이야 — 근데 수정을 음미하려면 먼저 고통을 느껴봐야 해.

drop 과의 연결

함수가 소유권을 가져가고 값을 반환 안 하면, 함수가 끝날 때 값이 drop 돼 — 힙 메모리가 거기서 바로 해제돼. 소유권과 lifetime 은 두 각도에서 들려주는 같은 이야기야: 누가 소유하느냐가 누가, 언제 해제하느냐를 정해.

Code

소유권이 함수 안팎으로 move 한다·rust
fn takes_ownership(s: String) {
    println!("got {s}");
} // 여기서 s 가 drop 됨 — 버퍼 해제

fn gives_back(s: String) -> String {
    s // 호출자한테 소유권을 돌려줌
}

fn takes_copy(n: i32) {
    println!("copy of {n}");
}

fn main() {
    let a = String::from("hi");
    takes_ownership(a);
    // println!("{a}");        // error[E0382]: a 가 함수로 move 됐음

    let b = String::from("yo");
    let b = gives_back(b);     // 돌려받아서 b 에 다시 묶음
    println!("still have {b}");

    let n = 5;
    takes_copy(n);
    println!("still have {n}"); // i32 는 Copy — n 은 멀쩡
}

External links

Exercise

각 단어를 대문자로 출력한 뒤 호출자가 vec 를 유지하게 반환하는 fn loudest(words: Vec<String>) -> Vec<String> 를 써봐. 값을 잃지 않으려고 그걸 반환하는 게 얼마나 어색한지 느껴봐. 그 느낌을 간직해 — borrowing 트랙이 그걸 사라지게 해.
Hint
넘길 때 move 돼서 사라지니까 words 를 반환하는 것뿐이야. 그 어색함이 바로 참조의 동기야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.