Trait

Trait

날짜
생성자
ShalomShalom
카테고리
rust
작성일
2023년 05월 15일
태그
rust
이전 블로그

Trait

fn largest(list: &[i32]) -> i32 { let mut largest = list[0]; for &item in list.iter() { if item > largest { largest = item; } } largest } /*Error!!: the name `largest` is defined multiple times `largest` must be defined only once in the value namespace of this module*/ fn largest(list: &[char]) -> char { let mut largest = list[0]; for &item in list.iter() { if item > largest { largest = item; } } largest }
오버로딩이 안됨
fn largest<T>(list: &[T]) -> T { let mut largest = list[0]; for &item in list.iter() { if item > largest { largest = item; } } largest } /* Err! T가 될 수 있는 모든 가능한 타입에 대해서 동작하지 않으리라는 것입니다. Trait으로 해결 */ fn main() { let numbers = vec![34, 50, 25, 100, 65]; let result = largest(&numbers); println!("The largest number is {}", result); let chars = vec!['y', 'm', 'a', 'q']; let result = largest(&chars); println!("The largest char is {}", result); }
  • 해결 방법
    • fn largest<T>(list: &[T]) -> T where T:PartialOrd//부등호에 관련된 트레잇(아마 정렬?) + Copy { let mut largest = list[0];//소유권 이동에 따른 Copy trait 필요 for &item in list.iter() { if item > largest { largest = item; } } largest } fn main() { let numbers = vec![34, 50, 25, 100, 65]; let result = largest(&numbers); println!("The largest number is {}", result); let chars = vec!['y', 'm', 'a', 'q']; let result = largest(&chars); println!("The largest char is {}", result); }
템플릿처럼 사용하지만 템플릿이랑은 다름
  • 예외가 발생할 수 있는 상황이 많기 때문(계산?)
  • 추상화할 수 있는 범위를 지정
struct Point<T, U> { x: T, y: U, } fn main() { let both_integer = Point { x: 5, y: 10 }; let both_float = Point { x: 1.0, y: 4.0 }; let integer_and_float = Point { x: 5, y: 4.0 }; }
러스트가 제네릭을 구현한 방식이 의미하는 바는 여러분이 제네릭 파라미터 대신 구체적인 타입을 명시했을 때와 비교해 전혀 느려지지 않을 것이란 점입니다!
→ 속도는 똑같다.
코드에 대해 단형성화(monomorphization) 를 수행함으로써 이러한 성능을 이루어 냈습니다. 단형성화란 제네릭 코드를 실제로 채워질 구체적인 타입으로 된 특정 코드로 바꾸는 과정을 말합니다. 컴파일러가 하는 일은 Listing 10-5에서 우리가 제네릭 함수를 만들 때 수행한 단계들을 반대로 한 것입니다. 컴파일러는 제네릭 코드가 호출되는 모든 곳을 살펴보고 제네릭 코드가 호출될 때 사용된 구체적인 타입에 대한 코드를 생성합니다.
→ 코드 복사가 일어난다.
$\large\color{black}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$

트레잇(동작들의 집합)

pub fn notify<T: Summarizable>(item: T) {//트레잇 바운드 println!("Trait Bound! {}", item.summary());//트레잇에 대해 정의가 안되어 있을때 실행 } fn main() { let article = NewsArticle { headline: String::from("Penguins win the Stanley Cup Championship!"), location: String::from("Pittsburgh, PA, USA"), author: String::from("Iceburgh"), content: String::from( "The Pittsburgh Penguins once again are the best hockey team in the NHL.", ), }; let tweet = Tweet { username: String::from("horse_ebooks"), content: String::from("of course, as you probably already know, people"), reply: false, retweet: false, }; let use_basic = UseBasic { username: String::from("horse_ebooks"), content: String::from("of course, as you probably already know, people"), }; println!("=========================================="); println!("article {}", article.summary()); println!("tweet {}", tweet.summary()); println!("use_basic {}", use_basic.summary()); notify(article.summary()); notify("tweet {}", tweet.summary()); println!("use_basic {}", use_basic.summary()); println!("=========================================="); } pub trait Summarizable { fn summary(&self) -> String { String::from("Basic trait!!!!!!!!") } } pub struct NewsArticle { pub headline: String, pub location: String, pub author: String, pub content: String, } impl Summarizable for NewsArticle {//Summarizable를 trait fn summary(&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 Summarizable for Tweet {//Summarizable를 trait fn summary(&self) -> String { format!("{}: {}", self.username, self.content) } } pub struct UseBasic { pub username: String, pub content: String, } impl Summarizable for UseBasic {}

실행 결과

========================================== Just trait! Penguins win the Stanley Cup Championship!, by Iceburgh (Pittsburgh, PA, USA) Just trait! horse_ebooks: of course, as you probably already know, people Just trait! Basic trait!!!!!!!!
Trait Bound! Penguins win the Stanley Cup Championship!, by Iceburgh (Pittsburgh, PA, USA) Trait Bound! horse_ebooks: of course, as you probably already know, people Trait Bound! Basic trait!!!!!!!!
===========================================
$\large\color{black}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$

트레잇 바운드(트레잇을 조합해보기)

//T: Display와 Clone의 trait이 구현되어 있어야 함 //U: Clone과 Debug의 trait이 구현되어 있어야함 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 {
$\large\color{black}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$

라이프 타임

모든 참조자는 라이프 타임을 가지고 있습니다!
{ let r; // -------+-- 'a // | { // | let x = 5; // -+-----+-- 'b r = &x; // | | } // -+ | // | println!("r: {}", r); // | // | // -------+ }

생략이 가능한 경우

//매개변수 라이프 타임은 순차적으로 정의가 된다. fn first_word(x: &str){//fn first_word<'a>(x: &'a str) //-| //..somthing // | } // | // | fn first_word(x: &str, y: &str){//fn first_word<'a, 'b>(x: &'a str, y: &'b str) // | //..somthing // | } // | // | //fn first_word<'a, 'b, 'c>(x: &'a str, y: &'b str,z: &'c str) // | fn first_word(x: &str, y: &str,z: &str){ // | //..somthing // | } //-| //하나의 라이프타임 매개변수만 있다면, //그 라이프타임이 모든 출력 라이프타임 파라미터들에 대입 //즉, 출력 파라미터의 라이프 타임을 굳이 정의 안해도 매개변수의 라이프 타임을 따라감 fn first_word(x: &str)->&str//fn first_word<'a>(x: &'a str)->&'a str { //..somthing } //fn first_word<'self>(x: &'self self, y: &'a str,z: &'a str)->&'self str // | fn first_word(&self, y: &str,z: &str)->&str { //..somthing }
/* fn longest(x: &'a str, y: &'b str) -> &'??? str {//어떤 라이프 타임을 넘겨줄지 모른다! if x.len() > y.len() { x } else { y } } */ fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } fn longest<'a,'b>(x: &'a str, y: &'b str) -> &'??? str { if x.len() > y.len() { x } else { y } } fn main() { let string1 = String::from("abcd"); let string2 = "xyz"; let result = longest("id", "id2"); println!("The longest string is {}", result); }

기타

struct ImportantExcerpt<'a> { part: &'a str,//구조체 안에서 } let s: &'static str = "I have a static lifetime.";//정적 라이프 타임

댓글

guest