일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 엘라스틱서치
- cleancode
- 그리디알고리즘
- Spring
- 자바
- ES
- Java
- Baekjoon
- 애자일기법
- 클린코드
- 프레임워크
- 코딩테스트
- 스프링
- 코드
- 백준
- Elasticsearch
- database
- 그리디
- JPA
- API
- framework
- 개발자
- spring boot
- 알고리즘
- 개발
- 애자일
- 데이터베이스
- 읽기쉬운코드
- 코딩
- 애자일프로그래밍
- Today
- Total
튼튼발자 개발 성장기🏋️
러스트 11 - References와 Borrowing 본문
다음 코드를 컴파일해보자.
fn main() {
let str = String::from("string");
let length = get_length(&str);
println!("================= get_length() finish! =================");
println!("str의 값 : [{}]", str);
println!("str의 길이 : [{}]", length);
}
fn get_length(func_str: &String) -> usize {
println!("================= get_length() start! =================");
println!("func_str의 값 : [{}]", func_str);
func_str.len()
}
"&"(Ampersand : 앰퍼샌드)라는 녀석이 새로 등장했다.
이 녀석은 참조자라 불리고 소유권을 가지지 않고 어떤 값을 참조하도록 해준다.
그림을 통해 보면 이해가 쉬울 것 같다..
※ 참조자 Ampersand의 반대는 역참조 "*"(Asterisk : 아스트리스크)를 사용한다.
Ampersand를 사용하여 소유권을 갖지 않기 때문에 scope 밖으로 벗어나도 메모리가 반환되지 않는다.
어차피 함수가 소유권이 없으니.. 반환할 필요도 없지요.
함수의 파라미터로 참조자를 받는 것을 "borrowing"이라고 부릅니다.
참고로 참조자도 기본적으로 불변의 성질을 가지고 있습니다.
하지만 이 참조자 역시 가변의 성질을 넣을 수 있습니다.
fn main() {
let mut str = String::from("string");
println!("str 값 : [{}]", str);
set_str(&mut str);
}
fn set_str(func_str: &mut String) {
func_str.push_str(" / new string");
println!("func_str 값 : [{}]", func_str);
}
참조자에 가변성을 추가하는 것은 rust로부터 큰 제한이 있습니다.
"해당 scope 내에서는 가변 참조자는 단 하나만 존재할 수 있어" 라는 것.
이 점. 유의하자.
도대체 왜?
이 제한의 이득(Benefit)이 따로 있다. 바로 compile time에 Data Race를 방지 할 수 있다는 것!
Data Race의 발생 조건은 다음과 같다.
- 두 개 이상의 포인터가 동시에 같은 데이터에 접근한다.
- 최소 하나 이상의 포인터가 데이터를 "쓰기"로 사용한다.
- 데이터에 대한 접근을 동기화(Synchronize)하는 데 사용되는 메커니즘이 없다.
Data Race는 정의되지 않은 동작을 발생 시키고 runtime에 추적할 때 fix하기 어렵다.
rust는 이런 좋지 않은 상황을 방지하기 위해 가변 참조자에 대한 제한을 걸어 둔 것이다!
- Dangling Reference
rust에서는 컴파일러가 참조자들이 dangling pointer가 되지 않도록 해준다.
만약 일부 데이터에 대한 참조가 있다면 컴파일러는 데이터 참조가 적용되기 전에 데이터가 scope를 벗어나지 않도록 해준다.
dangling pointer를 한 번 만들어보자.
fn main() {
let no = get_dangle_pointer();
}
fn get_dangle_pointer() -> &String {
let str = String::from("string");
&str
}
한 번 해결책을 찾길 바란다.
만약, 참조를 이해를 했다면, 바로 해결 방법이 떠오를 것이다.
'프로그래밍 > RUST' 카테고리의 다른 글
러스트 13 - 구조체 #1 (0) | 2019.03.10 |
---|---|
러스트 12 - 슬라이스 타입 (0) | 2019.03.03 |
러스트 10 - Ownership : 소유권 #2 (0) | 2019.03.02 |
러스트 9 - Ownership : 소유권 #1 (0) | 2019.02.24 |
러스트 8 - 주석 (0) | 2019.02.23 |