콘텐츠로 이동

Rust 출력

println!은 이미 여러 번 써 봤죠. 이 페이지에서는 앞으로 만나게 될 다른 출력 매크로들과, 각각을 언제 쓰면 좋은지 알아볼게요.

println!은 텍스트를 출력하고 끝에 줄바꿈을 붙여요. print!도 똑같이 출력하지만 줄바꿈을 붙이지 않아요.

fn main() {
print!("안녕하세요, ");
print!("세상");
println!("!");
}

실행 결과:

안녕하세요, 세상!
▶ 직접 실행해 보기

세 번의 호출이 모두 같은 줄에 출력된 걸 볼 수 있어요. 새 줄로 넘어가는 건 println!뿐이에요. 실제로는 거의 항상 println!을 쓰게 될 거예요. print!는 주로 한 줄을 조각조각 이어 붙여 만들 때 쓸모가 있어요.

{}를 자리 표시자로 쓰는 건 이미 봤어요. 자리를 채우는 방법은 두 가지예요. 문자열 뒤에 값을 넘기거나, 중괄호 안에 변수 이름을 바로 쓰면 돼요.

fn main() {
let name = "Ferris";
let age = 10;
println!("{}는 {}살이에요", name, age); // 위치 기반
println!("{name}는 {age}살이에요"); // 인라인 (결과는 같아요)
}

실행 결과:

Ferris는 10살이에요
Ferris는 10살이에요
▶ 직접 실행해 보기

두 줄 모두 같은 내용을 출력해요. 인라인 방식({name})이 조금 더 최근에 생긴 방식이고 보통 더 읽기 쉬워서, 쓸 수 있을 때는 이쪽을 추천해요.

format!: 출력하는 대신 문자열 만들기

섹션 제목: “format!: 출력하는 대신 문자열 만들기”

서식을 적용한 텍스트를 바로 출력하지 않고 String으로 받고 싶을 때가 있어요. 저장해 두거나 다른 함수에 넘기고 싶을 때처럼요. 그럴 때 쓰는 게 format!이에요. println!과 똑같이 동작하지만, 출력하는 대신 String을 돌려줘요.

fn main() {
let name = "Ferris";
let message = format!("안녕하세요, {name}!");
println!("{message}");
}

실행 결과:

안녕하세요, Ferris!
▶ 직접 실행해 보기

그냥 {}는 숫자, 문자열, 불리언처럼 자신을 텍스트로 표시하는 방법을 아는 값에만 쓸 수 있어요. 튜플이나 구조체처럼 더 복잡한 값에 {}를 쓰면 컴파일이 안 돼요. 그럴 때는 {:?}(“디버그” 형식)를 쓰세요.

fn main() {
let point = (3, 7);
println!("{:?}", point);
}

실행 결과:

(3, 7)
▶ 직접 실행해 보기

값이 클 때 여러 줄로 보기 좋게 출력하고 싶다면 {:#?}(예쁘게 출력하기, pretty-print)를 쓰세요.

fn main() {
let point = (3, 7);
println!("{:#?}", point);
}

실행 결과:

(
3,
7,
)
▶ 직접 실행해 보기

자주 쓰는 서식 몇 가지를 소개할게요.

fn main() {
let pi = 3.14159;
println!("{:.2}", pi); // 소수점 아래 2자리 -> 3.14
println!("{:5}", 42); // 너비 5로 맞추기 -> " 42"
println!("{:08.2}", pi); // 0으로 채우기 -> 00003.14
}

실행 결과:

3.14
42
00003.14
▶ 직접 실행해 보기

이걸 다 외울 필요는 없어요. 숫자를 줄 맞춰 정렬하거나 소수를 반올림해야 할 때 이런 방법이 있다는 것만 알아 두세요.

텍스트 정렬하기, 중괄호 출력하기

섹션 제목: “텍스트 정렬하기, 중괄호 출력하기”

너비는 텍스트에도 쓸 수 있고, 값을 어느 쪽에 붙일지도 고를 수 있어요. : 뒤에 <(왼쪽), >(오른쪽), ^(가운데) 중 하나를 쓰고 그다음에 너비를 써요. 맨 앞에 - 같은 채움 문자를 넣을 수도 있어요.

fn main() {
let coffee = 3.5;
let bagel = 2.25;
println!("{:-^20}", " MENU ");
println!("{:<12}{:>8}", "Item", "Price");
println!("{:<12}{:>8.2}", "Coffee", coffee);
println!("{:<12}{:>8.2}", "Bagel", bagel);
println!("{:<12}{:>8.2}", "Total", coffee + bagel);
}

실행 결과:

------- MENU -------
Item Price
Coffee 3.50
Bagel 2.25
Total 5.75
▶ 직접 실행해 보기

이 예제의 문자열은 일부러 영어로 두었어요. 너비는 글자 수로 세는데, 한글은 화면에서 영문자보다 두 배 넓게 표시되기 때문에 한글을 넣으면 줄이 어긋나 보이거든요.

{:>8.2}를 하나씩 읽어 보면, >는 오른쪽 정렬, 8은 너비, .2는 소수점 아래 두 자리라는 뜻이에요. 숫자를 오른쪽으로 정렬하면 소수점 위치가 나란히 맞아요. 영수증이나 표가 숫자를 오른쪽 정렬하는 이유예요.

출력에 진짜 {를 넣고 싶다면 어떻게 할까요? 중괄호는 “자리 표시자”라는 뜻이니까, 두 번 겹쳐 쓰면 돼요. {{는 {를, }}는 }를 출력해요.

fn main() {
println!("집합: {{{}, {}}}", 1, 2);
}

실행 결과:

집합: {1, 2}
▶ 직접 실행해 보기

물건 이름 "공책"과 가격 2.5를 저장한 다음, 공책 가격: $2.50을 출력해 보세요. 힌트: {:.2}는 소수점 아래 두 자리로 반올림해 주고, {price:.2}처럼 인라인으로도 쓸 수 있어요.

정답 보기
fn main() {
let item = "공책";
let price = 2.5;
println!("{item} 가격: ${price:.2}");
}

실행 결과:

공책 가격: $2.50
▶ 직접 실행해 보기

2. 라벨을 만들고 두 가지 방법으로 출력하기

섹션 제목: “2. 라벨을 만들고 두 가지 방법으로 출력하기”

format!으로 이름 "ferris"와 숫자 7을 이용해 ferris-7이라는 라벨을 만들어 보세요. 그리고 한 번은 {}로, 한 번은 {:?}로 출력해서 차이를 찾아보세요. 힌트: format!은 println!과 완전히 같은 자리 표시자를 써요.

정답 보기
fn main() {
let name = "ferris";
let id = 7;
let label = format!("{name}-{id}");
println!("{label}");
println!("{label:?}");
}

실행 결과:

ferris-7
"ferris-7"
▶ 직접 실행해 보기

디버그 출력은 텍스트를 따옴표와 함께 보여 줘서, 문자열이 정확히 어디서 시작하고 끝나는지 알 수 있어요. 값에 엉뚱한 공백이 섞여 있을 때 아주 유용해요.

  • println!은 줄바꿈과 함께 출력하고, print!는 줄바꿈 없이 출력해요.
  • {}와 {name}은 스스로를 Display할 수 있는 값을 위한 자리 표시자예요.
  • format!은 println!처럼 동작하지만, 출력하는 대신 String을 돌려줘요.
  • {:?}(와 {:#?})는 디버깅용으로 값을 출력해요. {}로 출력할 수 없는 값도 출력할 수 있어요.
  • {:.2}는 소수를 반올림하고, <, >, ^와 너비로 텍스트를 정렬하고, {{와 }}로 중괄호 자체를 출력해요.

이해도 점검

1. println!과 print!의 차이는 무엇일까요?

2. 튜플을 출력할 때 {} 대신 {:?}를 쓰는 이유는 무엇일까요?

점수: 0 / 2