Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

형식화된 출력

출력은 std::fmt에 정의된 일련의 매크로들에 의해 처리되며, 그 중 몇 가지는 다음과 같습니다:

  • format!: 형식화된 텍스트를 String에 씁니다.
  • print!: format!과 같지만 텍스트가 콘솔(io::stdout)에 출력됩니다.
  • println!: print!와 같지만 줄바꿈 문자가 추가됩니다.
  • eprint!: print!와 같지만 텍스트가 표준 에러(io::stderr)로 출력됩니다.
  • eprintln!: eprint!와 같지만 줄바꿈 문자가 추가됩니다.

모두 같은 방식으로 텍스트를 파싱합니다. 추가로, Rust는 컴파일 타임에 형식화의 올바름을 검사합니다.

fn main() {
    // 일반적으로 `{}`는 어떤 인자로든 자동으로 교체됩니다.
    // 이들은 문자열화될 것입니다.
    println!("{}일", 31);

    // 위치 인자를 사용할 수 있습니다. `{}` 안에 정수를 지정하면
    // 어떤 추가 인자가 교체될지 결정합니다. 인자는 형식 문자열
    // 바로 뒤에서 0부터 시작합니다.
    println!("{0}, 여기는 {1}입니다. {1}, 여기는 {0}입니다.", "앨리스", "밥");

    // 이름을 지정한 인자(named arguments)도 사용할 수 있습니다.
    println!("{subject} {verb} {object}",
             object="게으른 개",
             subject="빠른 갈색 여우",
             verb="넘어 뛰어넘다");

    // `:` 뒤에 형식 문자를 지정하여 다양한 형식화를 수행할 수 있습니다.
    println!("10진수:               {}",   69420); // 69420
    println!("2진수:                {:b}", 69420); // 10000111100101100
    println!("8진수:                {:o}", 69420); // 207454
    println!("16진수:               {:x}", 69420); // 10f2c

    // 지정된 너비로 텍스트를 오른쪽 정렬할 수 있습니다. 이 예시는
    // "    1"을 출력할 것입니다. (공백 4개와 "1" 하나로 총 너비 5가 됩니다.)
    println!("{number:>5}", number=1);

    // 숫자를 0으로 채울 수도 있습니다,
    println!("{number:0>5}", number=1); // 00001
    // 그리고 부호를 뒤집어 왼쪽 정렬할 수 있습니다. 이것은 "10000"을 출력합니다.
    println!("{number:0<5}", number=1); // 10000

    // 형식 지정자(format specifier)에 `$`를 붙여 명명된 인자를 사용할 수 있습니다.
    println!("{number:0>width$}", number=1, width=5);

    // Rust는 올바른 개수의 인자가 사용되었는지도 확인합니다.
    println!("제 이름은 {0}, {1} {0}입니다.", "본드");
    // FIXME ^ 누락된 인자를 추가하세요: "제임스"

    // fmt::Display를 구현하는 타입만 `{}`로 형식화할 수 있습니다. 사용자
    // 정의 타입은 기본적으로 fmt::Display를 구현하지 않습니다.

    #[allow(dead_code)] // 사용되지 않는 모듈에 대한 경고인 `dead_code`를 비활성화합니다
    struct Structure(i32);

    // `Structure`가 fmt::Display를 구현하지 않으므로 컴파일되지 않습니다.
    // println!("이 구조체 `{}`는 출력되지 않습니다...", Structure(3));
    // TODO ^ 이 줄의 주석을 해제해 보세요

    // Rust 1.58 이상에서는 주변 변수에서 직접 인자를 캡처할 수 있습니다.
    // 위와 마찬가지로, 이것은 "    1"(공백 4개와 "1")을 출력합니다.
    let number: f64 = 1.0;
    let width: usize = 5;
    println!("{number:>width$}");
}

std::fmt에는 텍스트 표시를 제어하는 많은 트레이트가 포함되어 있습니다. 그 중 중요한 두 가지의 기본 형태는 다음과 같습니다:

  • fmt::Debug: {:?} 마커를 사용합니다. 디버깅 목적으로 텍스트 형식을 지정합니다.
  • fmt::Display: {} 마커를 사용합니다. 보다 우아하고 사용자 친화적인 방식으로 텍스트 형식을 지정합니다.

여기서는 표준 라이브러리가 이러한 타입들에 대한 구현을 제공하기 때문에 fmt::Display를 사용했습니다. 커스텀 타입에 대해 텍스트를 출력하려면 더 많은 단계가 필요합니다.

fmt::Display 트레이트를 구현하면 타입을 String으로 변환할 수 있게 해주는 ToString 트레이트가 자동으로 구현됩니다.

_43행_의 #[allow(dead_code)]는 그 뒤에 오는 모듈에만 적용되는 속성입니다.

실습

  • 위 코드의 문제(FIXME 참고)를 수정하여 에러 없이 실행되도록 하세요.
  • Structure 구조체를 형식화하려는 줄의 주석을 제거해 보세요 (TODO 참고).
  • 표시되는 소수점 자릿수를 제어하여 Pi is roughly 3.142를 출력하는 println! 매크로 호출을 추가하세요. 이 연습을 위해 파이의 근사값으로 let pi = 3.141592를 사용하세요. (힌트: 표시할 소수점 자릿수를 설정하는 방법은 std::fmt 문서를 확인해야 할 수도 있습니다.)

참고:

std::fmt, 매크로, 구조체, 트레이트, 그리고 dead_code