본문 바로가기
개발/Rust

[Rust] 튜플(tuple)

by 77monkey 개발자 2023. 9. 28.
반응형

 

 

 

 

 

C/C++만 하신 분들에게는 튜플이 생소할 수 있을 것 같습니다. 배열과 같다고 생각하실 수도 있는데, 엄밀히 말하면 튜플은 배열과는 다릅니다. 튜플에 대해서 좀 더 알아보도록 합시다. 

 

튜플(tuple)

튜플(tuple)은 다양한 타입을 담습니다. 추후에 포스팅을 하겠지만 배열은 한 가지 타입을 담을 수 있습니다. 이런 점에서 차이가 발생합니다. 그렇다면 튜플에는 같은 타입을 담을 수 없는지 궁금할 수 있는데, 같은 타입을 담을 수 있습니다. 

 

튜플 선언

튜플은 () 사이에 데이터 타입을 넣어주고 쉼표(,)를 통해서 구별하여 선언합니다. 또한 튜플 변수 이름 뒤에 온점(.)을 쓰고 숫자를 씀으로써 튜플의 요소를 접근할 수 있습니다. 이때 접근 상수는 0부터 시작된다는 점 잊지 마시길 바랍니다. 

fn main() {
    let bloger = (77, "monkey");

    println!("bloger has has {} and {}", bloger.0, bloger.1);
}

한 가지 놓칠 수 있는 부분은 튜플에서 배열처럼 i번째 요소를 접근할 수 없다는 점입니다. 항상 상수로만 튜플의 인덱스를 접근할 수 있다는 점 잊지 마시길 바랍니다.

 

튜플 요소 바인딩

튜플의 요소를 인덱스를 통해서 접근하지 않고 분해할 수 있는 방법이 있습니다. 

fn main() {
    let bloger = (77, "monkey");

    let number = bloger.0;
    let name = bloger.1;
    println!("number: {}, name: {}", number, name);
}

아직 배우지 않은 부분인데 이렇게도 쓸 수 있다는 정도 알고 가시면 좋을 것 같아서 넣었습니다. 아래 코드는 튜플 요소를 추출하여 number와 name으로 바인딩을 하고 있습니다. 즉 위 코드에서 봤던 let number = bloger.0; 과 let name = bloger.1;을 match를 활용하여 표현한 것입니다. 개인적으로는 이 방법이 좀 더 직관적이게 튜플 요소를 사용하는데 좋다고 생각됩니다.

fn main() {
    let bloger = (77, "monkey");

    match bloger {
        (number, name) => {
            println!("number: {}, name: {}", number, name);
        }
    }
}

 

튜플 활용

튜플은 함수 리턴값으로 여러 값을 보낼 때 유용합니다. 예를 들면 아래 코드와 같습니다. 안 배운 것들이 있지만 흐름을 이해하는 게 중요한 것 같습니다. bloger_info()를 호출하여 number와 name으로 구성된 튜플을 리턴하게 됩니다. 그럼 그 리턴된 값들을 main함수에서의 number와 name으로 받게 됩니다. 일반적으로는 함수는 하나의 값만 돌려보내는데, 튜플을 이용하면 다양한 값을 리턴으로 받을 수 있습니다. 

fn bloger_info() -> (i32, String) {
    let number = 77;
    let name = String::from("monkey");

    (number, name)
}

fn main() {
    let (number, name) = bloger_info();
    println!("bloger number: {}", number);
    println!("bloger name: {}", name);
}

제로 튜플인 유닛 타입 ()을 자주 활용하게 됩니다. 유닛 타입은 주로 함수의 반환값이 없을 때 사용하게 됩니다. 또는 Result<(), std::io::Error>는 제대로 동작하지 않았을 때에는 error를 리턴 하지만, 그렇지 않은 경우에는 유닛 타입인 ()를 리턴하겠다는 의미입니다. 보통은 ok(())로 리턴하게 됩니다. 아래는 간단한 예시인데 이해를 돕기 위해 작성했습니다. 

fn test_func() -> Result<(), std::io::Error>
	// test code
    ok(())
}

 

마무리

튜플에 대해서 알아보았습니다. 배열과의 차이점에 대해서 다시 한 번 생각하시고, 유닛 타입인 ()에 대해서도 알아보았습니다. 생각보다 ok(()) 코드를 많이 보시게 될 텐데, 그때 유닛 타입을 써서 그렇구나라고 아시면 좋을 것 같습니다. 

반응형

'개발 > Rust' 카테고리의 다른 글

[Rust] 벡터(Vector)  (0) 2023.10.05
[Rust] 배열(array)  (0) 2023.10.02
[Rust] bool 타입  (0) 2023.09.27
[Rust] if 문  (0) 2023.09.04
[Rust] 변수 선언  (0) 2023.09.03