튜플 Tuples

튜플서로 다른 여러 타입의 값을 저장하는 컬렉션입니다. 소괄호 ()로 생성하며 모든 튜플 자체가 독립적인 값입니다. 타입 표기는 (T1, T2, ...)로 작성하고 T1, T2는 튜플 내 각 멤버의 타입을 의미합니다. 하나의 튜플에 원하는 개수의 데이터를 담을 수 있으므로 함수는 튜플을 이용해 여러 결과를 반환할 수 있습니다.

1 튜플을 함수 매개변수, 반환값으로 사용

// 튜플은 함수 입력 매개변수이자 반환값으로 사용 가능
fn reverse(pair: (i32, bool)) -> (bool, i32) {
    // let로 튜플 내부 멤버를 분해해 별개의 변수에 바인딩할 수 있음
    let (int_param, bool_param) = pair;
    // 순서가 바뀐 새 튜플 반환
    (bool_param, int_param)
}

fn main(){
    // (12, true)는 완전한 2요소 튜플로 단일 매개변수로 전달
	let res = reverse((12, true));
	// .0 인덱스로 반환된 튜플 첫 번째 요소 가져오기
	println!("{}", res.0);
}Code language: JavaScript (javascript)

컴파일 및 실행 결과

E:\rustdemo\demo>rustc demo.rs

E:\rustdemo\demo>demo
trueCode language: JavaScript (javascript)

2 튜플 구조체(Tuple Struct) 정의

#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);

fn main(){
    let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
    println!("{:?}", matrix);
}Code language: PHP (php)

튜플형 구조체: 구조체 이름 뒤에 소괄호와 타입 목록을 붙이며 이름 있는 필드가 없고 오직 순서로 요소를 구분합니다;

#[derive(Debug)] 파생 매크로: 구조체에 자동으로 Debug 트레이트를 구현해 {:?}로 디버그 정보 출력 지원;

Matrix(f32,f32,f32,f32)는 본질적으로 부동소수점 네 개를 감싼 특수 튜플입니다.

실행 중 경고가 출력되지만 무시해도 무방합니다

E:\rustdemo\demo>rustc demo.rs
warning: fields `0`, `1`, `2`, and `3` are never read
 --> demo.rs:2:15
  |
2 | struct Matrix(f32, f32, f32, f32);
  |        ------ ^^^  ^^^  ^^^  ^^^
  |        |
  |        fields in this struct
  |
  = help: consider removing these fields
  = note: `Matrix` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
  = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default

warning: 1 warning emitted


E:\rustdemo\demo>demo
Matrix(1.1, 1.2, 2.1, 2.2)Code language: JavaScript (javascript)

3 여러 타입 혼합 긴 튜플 + 첨자 인덱싱으로 값 가져오기

예시 먼저 확인

fn main(){

    // 여러 다른 데이터 타입이 담긴 긴 튜플
    let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

    // 튜플 첨자 인덱스로 내부 값 추출 가능
    println!("Long tuple first value: {}", long_tuple.0);
    println!("Long tuple second value: {}", long_tuple.1);
}Code language: JavaScript (javascript)

서로 다른 타입 데이터를 함께 저장할 수 있음 (부호 없는 정수, 부호 있는 정수, 부동소수점, 문자, 불리언 공존 가능);

튜플 인덱스 문법: 튜플변수.숫자, 인덱스는 0부터 시작;

  • .0 첫 번째 요소 가져오기,
  • .1 두 번째 요소 가져오기;
  • 이하 동일……

인덱스에는 고정 숫자 리터럴만 사용 가능하며 변수를 인덱스로 쓸 수 없습니다.

아래 정리되지 않은 내용——

2. 튜플 구조체(Tuple Struct) 정의


// 아래 구조체는 수업 후 연습용
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
Code language: PHP (php)

관련 핵심 지식

  1. 튜플형 구조체: 구조체 이름 뒤 소괄호가 오고 괄호 안은 타입 목록입니다. 필드 이름 없고 오직 순서로 요소 구분;
  2. #[derive(Debug)] 파생 매크로: 구조체에 자동으로 Debug 트레이트 구현, {:?}로 디버그 출력 지원;
  3. Matrix(f32,f32,f32,f32)는 본질적으로 부동소수점 네 개를 감싼 특수 튜플.

전체 예시는 아래

#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);

fn main() {
    // 1. 인스턴스 생성
    let mat = Matrix(1.0, 2.0, 3.0, 4.0);

    // 2. 출력 (#[derive(Debug)] 추가해야 {:?} 사용 가능)
    println!("행렬 인스턴스: {:?}", mat);

    // 3. 내부 요소 접근: .인덱스 사용
    let a = mat.0;
    let b = mat.1;
    let c = mat.2;
    let d = mat.3;
    println!("a={}, b={}, c={}, d={}", a, b, c, d);

    // 4. 분해로 값 추출
	// Matrix(m0, m1, m2, m3)는 분해 패턴 매칭, m0/m1/m2/m3는 직접 정의한 임시 변수로 구조체 내 튜플 멤버 4개의 값을 받음.
    let Matrix(m0, m1, m2, m3) = mat;
    println!("분해:{} {} | {} {}", m0, m1, m2, m3);
	

    // 5. 가변 행렬, mut으로 요소 수정
    let mut mat_mut = Matrix(0.0, 0.0, 0.0, 0.0);
    mat_mut.0 = 10.0;
    mat_mut.3 = 99.0; // 값 수정 가능
    println!("가변 행렬: {:?}", mat_mut);
}Code language: PHP (php)

실행 결과

E:\rustdemo\demo>demo
행렬 인스턴스: Matrix(1.0, 2.0, 3.0, 4.0)
a=1, b=2, c=3, d=4
분해:1 2 | 3 4
가변 행렬: Matrix(10.0, 0.0, 0.0, 99.0)

3 여러 타입 혼합 긴 튜플 + 첨자 인덱싱으로 값 가져오기

fn main() {
 
    // 여러 다른 데이터 타입이 담긴 긴 튜플
    let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

    // Values can be extracted from the tuple using tuple indexing.
    // 튜플 첨자 인덱스로 내부 값 추출 가능
    println!("Long tuple first value: {}", long_tuple.0);
    println!("Long tuple second value: {}", long_tuple.1);
}
Code language: JavaScript (javascript)

실행 결과

E:\rustdemo\demo>demo
Long tuple first value: 1
Long tuple second value: 2

정리

  1. 튜플 핵심 특징:서로 다른 타입 데이터를 함께 저장할 수 있음 (부호 없는 정수, 부호 있는 정수, 부동소수점, 문자, 불리언 공존 가능);
  2. 튜플 인덱스 문법:튜플변수.숫자, 인덱스는 0부터 시작;
    • .0 첫 번째 요소 가져오기,
    • .1 두 번째 요소 가져오기;
  3. 인덱스에는 고정 숫자 리터럴만 사용 가능하며 변수를 인덱스로 쓸 수 없다.

4 튜플 중첩

fn main() {
 
    // 튜플 멤버 자체가 튜플일 수 있으며 중첩 지원
    let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);

 
    // 튜플 디버그 출력 지원
    println!("tuple of tuples: {:?}", tuple_of_tuples);
	
	// . 두 번 연속 사용해 값 출력
	println!("tuple of tuples: {:?}", tuple_of_tuples.0.1); // 2 출력
}
Code language: JavaScript (javascript)

출력 결과

E:\rustdemo\demo>demo
tuple of tuples: ((1, 2, 2), (4, -1), -2)
tuple of tuples: 2

정리

  1. 다중 레벨 튜플 중첩 지원, 외부 튜플 요소는 하위 튜플 가능;
  2. 요소 개수 ≤12인 튜플은 자동으로 Debug 트레이트 구현되며 포맷 지정자 {:?}로 전체 내용 직접 출력 가능.

5 초장 튜플 출력 제한(컴파일 오류)


   fn main() {
 
    // 요소가 12개 넘는 초장 튜플은 Debug로 직접 출력 불가
    let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
    println!("Too long tuple: {:?}", too_long_tuple);
    // 힌트: 위 두 줄 주석 해제하면 컴파일러 오류 확인 가능
}
Code language: JavaScript (javascript)

컴파일 오류 메시지

E:\rustdemo\demo>rustc demo.rs
error[E0277]: `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})` doesn't implement `Debug`
 --> demo.rs:5:38
  |
5 |     println!("Too long tuple: {:?}", too_long_tuple);
  |                               ----   ^^^^^^^^^^^^^^ `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})` cannot be formatted using `{:?}` because it doesn't implement `Debug`
  |                               |
  |                               required by this formatting parameter
  |
  = help: the trait `Debug` is not implemented for `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})`
  = help: the following other types implement trait `Debug`:
            ()
            (A, Z, Y, X, W, V, U, T)
            (B, A, Z, Y, X, W, V, U, T)
            (C, B, A, Z, Y, X, W, V, U, T)
            (D, C, B, A, Z, Y, X, W, V, U, T)
            (E, D, C, B, A, Z, Y, X, W, V, U, T)
            (T,)
            (U, T)
          and 5 others
  = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.Code language: PHP (php)

정리

Rust 표준 라이브러리는 오직요소 개수 0~12 튜플에만 Debug 트레이트 자동 파생;

요소 개수>12인 튜플은 내장 Debug 구현이 없으며 {:?}로 직접 출력 시 컴파일 실패.

위 숫자 13을 지우고 테스트하면 오류가 사라지는지 확인할 수 있습니다

6 튜플 매개변수 함수 호출, 교환 결과 확인

// 튜플은 함수 입력 매개변수이자 반환값으로 사용 가능
fn reverse(pair: (i32, bool)) -> (bool, i32) {
    // let로 튜플 내부 멤버를 분해해 별개의 변수에 바인딩할 수 있음
    let (int_param, bool_param) = pair;
    // 순서가 바뀐 새 튜플 반환
    (bool_param, int_param)
}

fn main() {
 
    let pair = (1, true);
    println!("Pair is {:?}", pair);

    println!("The reversed pair is {:?}", reverse(pair)); // 위 reverse 호출해서 순서 교환
}Code language: JavaScript (javascript)

실행 결과

E:\rustdemo\demo>demo
Pair is (1, true)
The reversed pair is (true, 1)Code language: JavaScript (javascript)

정리

  1. 일반적인 2요소 튜플은 튜플을 받는 함수에 실인자로 직접 전달 가능;
  2. 함수는 완전히 새로운 튜플을 반환하며 원본 튜플 pair는 수정되지 않음.

7 단일 요소 튜플 쉼표 특수 규칙(자주 틀리는 포인트)


   fn main() {
 
    // 단일 요소 튜플 생성 시 쉼표 필수, 단순 괄호로 감싼 리터럴과 구분하기 위함
    println!("One element tuple: {:?}", (5u32,)); 
    println!("Just an integer: {:?}", (5u32));

}Code language: JavaScript (javascript)

정리

  • (5u32):쉼표 없이 단순 숫자
  • (5u32,):끝에 쉼표가 있어유효한 단일 요소 튜플, 타입은 (u32,);
  • (5u32):쉼표 없이 단순 숫자
  • 답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다