[Rust] 8장 제네릭

1. 제네릭 (Generics)

Rust에서 Generics(제네릭)은 데이터 타입에 대한 추상화를 제공해 코드의 재사용성을 높이고, 타입 안정성을 유지하는 데 도움을 주며, 제네릭을 사용해 특정 타입에 의존하지 않고 함수, 구조체, 열거형 등을 정의할 수 있습니다.


2. 기본 문법

제네릭은 <T>와 같은 형식으로 사용합니다. T 부분에는 타입 매개변수를 나타냅니다.

  • 함수에서 제네릭
fn print_value<T: std::fmt::Debug>(value: T) {
    println!("{:?}", value);
}

fn main() {
    print_value(10); // 정수
    print_value(10.0); // 실수
    print_value("Hello, World!"); // 문자열
    print_value(true); // 불리언
}
  • 구조체에서의 제네릭
struct Pair<T,U> {
    first: T,
    second: U,
}

fn main() {
    let pair = Pair { first: 10, second: "Ten" };
    println!("first: {}, second: {}", pair.first, pair.second)
}
  • 열거형에서 제네릭
enum Option<T> {
    Some(T),
    None,
}

fn main() {
    let some_number = Option::Some(5);
    let some_value: Option<i32> = Option.None;

}

3. 제네릭 제약 조건

제네릭 타입에 제약을 추가할 수 있습니다. 이를 통해 특정 트레이트를 구현한 타입만 사용할 수 있습니다.

fn print_length(s: &str) {
    println!("Length: {}", s.len());
}

fn main() {
    let my_string = String::from("Hello");
    print_length(&my_string); 
}

4. 생명 주기와의 조합

제네릭과 생명주기(life-cycle)를 함께 사용할 수 있습니다. 생명 주기를 사용해 참조의 유효성을 보장합니다.

fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    if s1.len() > s2.len() {
      s1
    } else {
        s2
    }
}

fn main() {
    let str1 = String::from("Hello");
    let str2 = String::from("Rust!");
    let result = longest(&str1, &str2);
    println!("Longest string is {}", result); // Longest string is Rust!
}

5. 재네릭 코드 재사용

  • 제네릭 함수

제네릭 함수를 사용해 다양한 타입에 대해 동일한 기능을 수행할 수 있습니다. 두 값을 비교하는 함수를 구현해보겠습니다.

fn compare<T: PartialOrd> (a: T, b: T) -> T {
    if a < b {
        a
    } else {
        b
    }
}

fn main() {
    let a = 10;
    let b = 20;
    let smaller = compare(a, b);
    println!("The smaller number is: {}", smaller);

    let str1 = "Apple";
    let str2 = "Banana";
    let smaller_str = compare(str1, str2);
    println!("The Smaller string is: {}", smaller_str);
}
  • 제네릭 구조체

제네릭 구조체를 사용해 다양한 타입의 데이터를 저장할 수 있는 구조체를 정의합니다.

struct Pair <T, U> {
    first: T,
    second: U,
}

fn main() {
   let integer_pair = Pair { first: 10, second: 20};
   let string_pair = Pair { first: "Apple", second: "Banana"};

   println!("The integer pair is: ({}, {})", integer_pair.first, integer_pair.second);
   println!("The string pair is: ({}, {})", string_pair.first, string_pair.second);
}
  • 제네릭 열거형

제네릭 열거형을 사용해 다양한 타입의 값을 가질 수 있는 열거형을 정의합니다.

enum Option<T> {
    On(T),
    None,
}

fn main() {
    let some_bool = Option::On(true);
    let _none_bool: Option<i32> = Option::None; 

   // Option example
   match some_bool {
     Option::On(value) => println!("Power is on: {}", value),
     Option::None => println!("Power is off"),
   }
}
  • 제네릭과 트레이트

제네릭을 사용해 특정 트레이트를 구현하는 타입만을 제한할 수 있습니다. 예를 들어, Clone 트레이트를 구현한 타입만을 사용하는 함수입니다.

fn duplicate<T: Clone>(value: T) -> (T, T) {
    (value.clone(), value)
}

fn main() {
    let number = 10;
    let (number1, number2) = duplicate(number);
    println!("Duplicate number: ({} and {})", number1, number2);

    let text = String::from("Hello");
    let (text1, text2) = duplicate(text);
    println!("Duplicate text: ({} and {})", text1, text2);
}

 

 

GitHub - Koras02/rust-tutorial: https://thinky.tistory.com/category/Back-End/Rust

https://thinky.tistory.com/category/Back-End/Rust. Contribute to Koras02/rust-tutorial development by creating an account on GitHub.

github.com

 

LIST

'Back-End > Rust' 카테고리의 다른 글

[Rust] 10장 트레이트  (0) 2025.03.25
[Rust] 9장 동시성  (0) 2025.03.20
[Rust] 7장 모듈  (0) 2025.03.10
[Rust] 6장 에러 처리  (0) 2025.03.08
[Rust] 5장 패턴 매칭(Pattern Matching)  (0) 2025.03.06