RUST 제네릭, 트레이트, 라이프타임

Alpha, Orderly·2024년 6월 2일

RUST

목록 보기
8/11

제네릭

  • 함수 시그니처나 구조체의 아이템에 다양한 데이터 타입을 쓰도록 할수 있다.
fn largest<T>(list: &[T]) -> &T {
    let mut largest = &list[0];

    for item in list {
        if item > largest {
            largest = item;
        }
    }

    largest
}
  • T를 이용해 제네릭 함수를 선언한 예시
  • 허나 이 경우 T가 비교문이 구현된것인지 확인할수 없어 에러가 나온다.

제네릭 구조체

struct Point<T> {
    x: T,
    y: T,
}

struct Point<T, U> {
    x: T,
    y: U,
}

제네릭 열거형

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

제네릭 메서드

impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
}
  • 특정 타입에만 정의할수도 있다.
  • impl 뒤에 <T> 를 붙혀 Point 뒤가 제네릭임을 알린다.
impl Point<f32> {
    fn distance_from_origin(&self) -> f32 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
}
  • Point 뒤가 제네릭임을 알릴 필요가 없어 impl 뒤에 아무것도 없다.
  • 제네릭 코드를 사용하는 코드를 컴파일시 구체적인 타입으로 변환하기 때문에 성능적 차이가 없다.

트레이트

  • 특정한 타입이 가지며 다른 타입과 공유하는 기능
  • interface

정의하기

pub trait Summary {
    fn summarize(&self) -> String;
}

트레이트 구현하기

pub struct NewsArticle {
    pub headline: String,
    pub location: String,
    pub author: String,
    pub content: String,
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}, by {} ({})", self.headline, self.author, self.location)
    }
}

pub struct Tweet {
    pub username: String,
    pub content: String,
    pub reply: bool,
    pub retweet: bool,
}

impl Summary for Tweet {
    fn summarize(&self) -> String {
        format!("{}: {}", self.username, self.content)
    }
}

- impl 트레이트 이름 for 구조체 이름 {
	// 구현
}

트레이트에 기본 구현 추가

pub trait Summary {
    fn summarize(&self) -> String {
        String::from("(Read more...)")
    }
}

impl Summary for NewsArticle {}
// 와 같이 사용 가능하다.

매개변수로 트레이트

pub fn notify(item: &impl Summary) {
    println!("Breaking news! {}", item.summarize());
}
  • impl 키워드와 구현한 트레이트의 이름이 주어진다.
  • Summary trait 가 구현된 것만 사용하게 한다.
pub fn notify<T: Summary>(item: &T) {
    println!("Breaking news! {}", item.summarize());
}
  • 와 같이 사용할수도 있다.
  • 둘이 같은 타입으로 강제된다.
pub fn notify(item: &(impl Summary + Display)) {
  • 여러 트레이트의 구현을 사용할수도 있다.
pub fn notify<T: Summary + Display>(item: &T) {
fn some_function<T: Display + Clone, U: Clone + Debug>(t: &T, u: &U) -> i32 {
fn some_function<T, U>(t: &T, u: &U) -> i32
where
    T: Display + Clone,
    U: Clone + Debug,
{
  • where을 쓴 예시

Trait를 구현하는 타입을 반환

fn returns_summarizable() -> impl Summary {
    Tweet {
        username: String::from("horse_ebooks"),
        content: String::from(
            "of course, as you probably already know, people",
        ),
        reply: false,
        retweet: false,
    }
}
  • impl 트레이트 이름 을 반환한다.

조건부 메서드

impl<T: Display + PartialOrd> Pair<T> {
    fn cmp_display(&self) {
        if self.x >= self.y {
            println!("The largest member is x = {}", self.x);
        } else {
            println!("The largest member is y = {}", self.y);
        }
    }
}
  • T가 Display와 PartialOrd를 모두 구현했을때만 메서드가 구현된다.
impl<T: Display> ToString for T {
    // --생략--
}
  • Display 가 구현된 모든 타입에서 ToString 을 구현한다.
profile
만능 컴덕후 겸 번지 팬

0개의 댓글