강의

멘토링

로드맵

Inflearn Community Q&A

suhanjung5396's profile image
suhanjung5396

asked

Introduction to and use of Rust, an elegant, high-performance programming language

To lend without transferring ownership | Lease

&r1 을 써야하는지 r1을 써야하는지?

Resolved

Written on

·

117

1

fn main() {

let mut s = String::from("헬로");

let r1 = &s;

let r2 = &s;

println!("r1 = {}, r2= {}", r1, r2);

}

여기서 println! 부분에 r1을 사용하건 &r1을 사용하건 둘다 "헬로" 로 같은 값이 나옵니다.

엄밀하게 말하면 r1은 문자열s의 주소값일 것 같아서 질문 드립니다.

그리고 주소값을 바탕으로 실제 값을 가져오는 건 일반적으로 &연산자가 아닌 *연산자를 사용하지 않는지요?

rustwebassembly

Quiz

46% of people got it wrong. Give it a try!

Rust가 다른 언어와 차별화되는 주요 메모리 관리 방식은 무엇일까요?

런타임에 가비지 컬렉터가 메모리를 자동 정리한다.

개발자가 명시적으로 메모리를 할당하고 해제한다.

컴파일 시점에 소유권 규칙으로 메모리 안전성을 검사한다.

메모리 사용량을 최소화하기 위해 모든 데이터를 스택에 저장한다.

Answer 1

0

hatemogi님의 프로필 이미지
hatemogi
Instructor


fn main() {
    let s = String::from("헬로");

    let r1: &String = &s;
    let r2: &&String = &r1;
    let r3: &&&String = &&&s;

    println!("r1 = {}, r2= {}, r3 = {}", r1, r2, r3);
}

수강 및 좋은 질문 감사합니다.


우선, println!("{}", v)에서 어떤 값이 출력됐다고 해서, 그 값이 그대로 보인 게 아니라는 점을 명확히 하면 좋겠습니다.

질문에 적어주신대로, r1은 s의 주소값, 러스트 용어로 말하자면 참조값인 게 맞습니다. 둘의 타입이 명백히 다르죠. s의 타입은 String이고, r1의 타입은 &String입니다.

단지, println!매크로에 활용되는 std::fmt::Display 트레이트 구현과 러스트의 deref 규칙 때문에 화면에는 "헬로"라는 문자열이 잘 보인 것 뿐입니다.

강의에 따로 다룬 내용이 아니므로 자세히 설명드리기는 어렵습니다만, 간단하게 적자면, println!에 {}자리에 찍을 대상들은 Display::fmt 메소드를 호출하게 되어있고, 참조값인 경우 원형(참조를 해제해서)의 fmt까지 쫓아가서 출력할 수 있는 기능이 있습니다.

따라서 몇 중으로 참조한 참조값이든 원래 타입의 값이 Display할 수 있는 값이라면 같은 내용이 화면에 보이는 것입니다.

질문에 적어주신, r1을 써야하느냐, &r1을 써야 하느냐는 질문에는, 상황에 따라 다를 수 있지만, 일반적으로 이미 r1이 참조값이므로, 그걸 또 참조할 일은 흔치는 않겠다고 말씀드리겠습니다. (하지만 C/C++같은 언어에서 때로 이중포인터를 쓰기도 하니, 비슷한 용례로 쓰일 수도 있겠죠)

더 궁금하신 내용이 있으시면 편히 말씀주세요 

suhanjung5396's profile image
suhanjung5396

asked

Ask a question