개발_기록용

RUST 스터디[RUST vs C++] 22. Borrowing 본문

RUST 스터디

RUST 스터디[RUST vs C++] 22. Borrowing

나폴나폴 2024. 6. 18. 13:14
728x90

https://google.github.io/comprehensive-rust/borrowing.html

 

Borrowing - Comprehensive Rust 🦀

This segment should take about 55 minutes. It contains: SlideDuration Borrowing a Value10 minutes Borrow Checking10 minutes Borrow Errors3 minutes Interior Mutability10 minutes Exercise: Health Statistics20 minutes

google.github.io

22.1 Borrowing a Value

아래 내용에서 소유권의 내용을 다뤘는데, 내가 계속 쓰고 싶어서 소유권을 안 넘기고 싶은 순간이 있다.

그럴 땐, 빌려주면 된다.

https://dev-check.tistory.com/24

 

RUST 스터디[RUST vs C++] 19. Memory Management

https://google.github.io/comprehensive-rust/memory-management.html Memory Management - Comprehensive Rust 🦀This segment should take about 1 hour. It contains: SlideDuration Review of Program Memory5 minutes Approaches to Memory Management10 minutes Own

dev-check.tistory.com

 

 

add(&p1, &p2)와 같이, p1과 p2의 값의 소유권을 레퍼런스로 빌려주면

함수 끝나고 나서는 소유권을 다시 돌려받기 때문에 계속 쓸 수 있다.

빌려준 상태에서 중간에 뺏어올 수 없다. 소유권을 누가 빌려간 상태니까.
근데 우리가 비디오를 빌려와서 다른 사람한테 빌려줄 수 있듯이, 빌려온 소유권을 또 빌려줄 수 있다(!)
=> 위의 add함수에서 sub 함수로 p1, p2를 넘겨준 것과 같다.

 

*불필요한 복사를 막기 위해 C++에서 만든게 Rvalue와 Rvalue reference.

Rvalue는 123처럼 문장이 끝나면 사라질 값이다.

근데 Rvalue reference는 &123 같은 것이다. 이걸 왜 만들었을까?

 

let p3 = add(&p1, Point(20, 30)); 을 잘 보자.

위처럼 Point(20, 30)으로 인자를 넘겨주면, 값의 불필요한 복사가 일어난다.

 

반면, &Point(20, 30)으로 넘겨주면, 복사할 필요 없이 넘겨줄 수 있다.

그래서 이런 불필요한 복사를 막을 수 있으므로, 성능적 관점에서 향상할 수 있기에 만들어졌다.

 

22.2 Borrow Checking

Rust에선 Borrow Checker가 있다. 우리가 잘 빌렸는지 시스템 내부적으로 체크하는 역할!

쓰기가 가능한 reference는 하나만 해놓고, 읽기 가능한 reference는 여러개 가능하도록 했음.

 

c는 a의 값을 받아와서 값을 쓴다.

자, 그럼 이 코드 돌아갈까? 안 돌아간다.

앞에서 b를 통해 이미 immutable하게 읽기 전용으로 빌린 상태이므로. 또 빌릴려면 immutable하게만 빌릴 수 있다.

 

22.3 Borrow Errors

 

첫번째 예제에서 벡터의 2번째 요소를 빌린 후, push를 한다. 이 구문은 돌아갈까? 안 돌아간다.

이미 elem에서 immutable하게 빌렸으니, push가 불가!

 

두번째 예제는 가능할까? 안 된다.

for elem in &vec 로 쓴 것 자체가 이미 immutable하게 빌린 과정이므로, push 불가!

 

22.4 Interior Mutability

List같은거 만들 때 Rc를 쓰긴 하는데, 읽기 전용이니까 반쪽 짜리이다.

이걸 바꿀 수 있어야 의미있지 않을까?

=> 그래서 Rust에선 Interior Mutability (내부 가변성) 패턴을 제공한다.

exclusive(예외적으로) shared reference 안에서 접근을 가능하게 해준다.

 

 

Rc = 장점 : 레퍼런스 카운팅 (공유) / 단점 : 읽기 전용
RefCell = 장점 : 빌려서 쓰기 가능 / 단점 : 공유 안 됨.

그래서, 이 두개가 모인게 Rc<RefCell<T>> : 굉장히 Rust에서 많이 쓰이는 패턴.

 

*Cell

: 비슷한게 Cell이 있다. 얘는 reference를 허용하지 않는다는 특징이 있다.

그러므로 빌림 규칙은 성립되지 않고, 그러니 잘 안 쓰이고 그냥 값을 가져오거나 세팅하거나 하는 타입.

 

반응형
Comments