튜플은 서로 다른 여러 타입의 값을 저장하는 컬렉션입니다. 소괄호 ()로 생성하며 모든 튜플 자체가 독립적인 값입니다. 타입 표기는 (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)
관련 핵심 지식
- 튜플형 구조체: 구조체 이름 뒤 소괄호가 오고 괄호 안은 타입 목록입니다. 필드 이름 없고 오직 순서로 요소 구분;
#[derive(Debug)]파생 매크로: 구조체에 자동으로Debug트레이트 구현,{:?}로 디버그 출력 지원;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
정리
- 튜플 핵심 특징:서로 다른 타입 데이터를 함께 저장할 수 있음 (부호 없는 정수, 부호 있는 정수, 부동소수점, 문자, 불리언 공존 가능);
- 튜플 인덱스 문법:
튜플변수.숫자, 인덱스는 0부터 시작;.0첫 번째 요소 가져오기,.1두 번째 요소 가져오기;
- 인덱스에는 고정 숫자 리터럴만 사용 가능하며 변수를 인덱스로 쓸 수 없다.
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
정리
- 다중 레벨 튜플 중첩 지원, 외부 튜플 요소는 하위 튜플 가능;
- 요소 개수 ≤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)
정리
- 일반적인 2요소 튜플은 튜플을 받는 함수에 실인자로 직접 전달 가능;
- 함수는 완전히 새로운 튜플을 반환하며 원본 튜플
pair는 수정되지 않음.
7 단일 요소 튜플 쉼표 특수 규칙(자주 틀리는 포인트)
fn main() {
// 단일 요소 튜플 생성 시 쉼표 필수, 단순 괄호로 감싼 리터럴과 구분하기 위함
println!("One element tuple: {:?}", (5u32,));
println!("Just an integer: {:?}", (5u32));
}Code language: JavaScript (javascript)
정리
(5u32):쉼표 없이 단순 숫자
(5u32,):끝에 쉼표가 있어유효한 단일 요소 튜플, 타입은 (u32,);
(5u32):쉼표 없이 단순 숫자 Previous: 리터럴과 연산자