🦀 Rust
[Rust 입문] 9. 제네릭, 트레잇
date
Mar 23, 2023
slug
rust-generic
author
status
Public
tags
Rust
독학
summary
Rust의 Genetic, Trait에 대한 설명입니다.
type
Post
thumbnail
category
🦀 Rust
updatedAt
Mar 23, 2023 11:25 AM
제네릭
많은 언어들처럼 rust도 제네릭을 지원한다. rust는 구조체나 함수, 메소드, 열거형 등에 대해 제네릭을 사용할 수 있다.
fn main() { let test_int = Test{data: 123}; let test_str = Test{data: "str"}; let get_int = test_int.get(); let get_str = test_str.get(); println!("{}", get_int); println!("{}", get_str); } struct Test<T> { data: T } impl<T> Test<T> { fn get(&self) -> &T { &self.data } }
트레잇
트레잇(trait) 은 특정 타입이 가지고 있는 기능, 다른 타입들과 함께 공유할 수도 있는 기능에 대해 알려주는 역할을 한다.
만약 제네릭 타입의 파라미터를 사용할 때 컴파일 타임에 해당 제네릭 타입이 어떤 트레잇을 구현한 타입이여야 함을 명시한다. 그렇지 않으면 타입에 없는 기능이 들어오게 될 때 문제가 되기 때문이다.
트레잇의 정의
rust에서 트레잇을 정의하는 것은 특정 기능을 수행하기 위해 필요한 메소드들의 시그니처들을 묶는 것이다.
표준 라이브러리에 특정 값을 문자열로 변환하고자 하는 트레잇이 정의되어 있는데 다음과 같이 정의되어 있다.
pub trait ToString { fn to_string(&self) -> String; }
문자열로 리턴하는 메소드의 시그니처가 정의되어 있으며 별도로 트레잇을 정의하고자 하는 경우 여러개를 정의하여도 제한은 없다.
만약 기본 동작을 정의하고 싶다면 메소드 시그니처와 구현 블록까지 구현한다.
pub trait Summarizable { fn summary(&self) -> String { String::from("(Read more...)") } }
타입에 대한 트레잇 구현
특정 타입에 대해 트레잇을 구현하면 그 타입은 트레잇에 정의된 기능을 실행할 수 있다.
좌표를 나타내는 구조체 Pos를 정의하고 이 구조체 타입에 대해 ToString 트레잇을 구현한 예이다.
pub struct Pos { pub x: i32, pub y: i32 } impl ToString for Pos { fn to_string(&self) -> String { format!("x : {}, y : {}", self.x, self.y) } }
위와 같이 구현하면 Pos 타입에 대해 to_string 메소드를 사용할 수 있게 된다.
fn main() { let p = Pos{x: 10, y: 20}; let s = p.to_string(); println!("{}", s); // x : 10, y : 20 }
트레잇 바운드
제네릭을 사용할 때의 문제는 타입이 지원하지 않는 연산 혹은 동작을 시도하게 될 수도 있다는 점이다. 그래서 제네릭을 선언할 때 제네릭 타입에 대해 트레잇 바운드를 사용해 해당 트레잇을 구현한 타입만 받을 수 있게 제한한다.
fn main() { let p = Pos{x: 10, y: 20}; print_using_tostring(p.to_string()); } pub struct Pos { pub x: i32, pub y: i32 } impl ToString for Pos { fn to_string(&self) -> String { format!("x : {}, y : {}", self.x, self.y) } } fn print_using_tostring<T: ToString>(t: T) { let s = t.to_string(); println!("to_string -> {}", s); }
print_using_tostring 함수에서 제네릭 타입 T에 대해 to_string() 메소드가 구현되어 있는 타입만 받기 위해 트레잇 바운드 T: ToString 을 사용하였다. 여러 트레잇을 합칠 경우 + 연산자로 합힐 수 있다.