C.W.K.
Stream
Lesson 07 of 07 · published

매일 쓰게 될 표준 Trait

~12 min · traits, std, derive, from-into

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

네 trait 을 쓰는 것보다 표준 라이브러리 trait 을 구현하는 데 시간을 더 써. 한 줌이 계속 나와 — 걔들을 알면 '이거 왜 컴파일 안 돼?' 가 '아, 저거 derive 해야지' 로 바뀌어.

derive 가능한 빅 파이브

Debug ({:?} 로 출력), Clone (명시적 깊은 복사), Copy (암묵적 비트 복사), PartialEq (== 연산자), Default (::default() 값) 는 다 #[derive(...)] 로 자동 생성돼. struct 위에 붙이면 컴파일러가 뻔한 구현을 써줘. #[derive(Debug, Clone, PartialEq)] 를 반사적으로 치게 돼.

Display vs Debug

Debug 는 개발자용 (derive 가능, {:?}); Display 는 최종 사용자용 (손으로 구현, {}). 분리는 의도적이야: 지저분한 내부 view 랑 다듬은 사용자 대면 view 는 다른 일이라, Rust 가 다른 trait 으로 만들어.

From 과 Into: 변환

From<A> for B 를 구현하면 B::from(a) 를 얻어 — 그리고 a.into() 도 공짜야, IntoFrom 에서 자동 파생되니까. 이 쌍이 사방에 있어: 에러 변환 (? 연산자가 From 으로 에러 타입을 변환해), 타입 래퍼, ergonomic 생성자. From 을 구현해, Into 를 직접 말고.

먼저 derive, 꼭 필요하면 구현. 기계적 trait (Debug, Clone, PartialEq, Default) 엔 #[derive(...)] 로 손 뻗어. 진짜 로직이 필요한 것만 손으로 구현해 — 사람용 포맷팅엔 Display, 변환엔 From, 커스텀 순회엔 Iterator. 보일러플레이트는 컴파일러가 쓰게 둬.

이게 모든 것으로의 다리야

여기서부터 표준 라이브러리가 네 놀이터고, 다 trait 이야: Iterator 가 Collections 트랙을, From 이 에러 처리를, Send/Sync 가 동시성을 움직여. 이제 Rust 의 나머지가 그 위에 지어진 개념 하나 — trait — 을 가졌어.

Code

기계적인 건 derive, 의미 있는 건 구현·rust
use std::fmt;

#[derive(Debug, Clone, PartialEq)] // 기계적 trait: derive
struct Celsius(f64);
struct Fahrenheit(f64);

impl fmt::Display for Celsius {       // 사람용 포맷팅: 손으로 작성
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}°C", self.0)
    }
}
impl From<Celsius> for Fahrenheit {   // 변환: From 이 Into 를 공짜로 줌
    fn from(c: Celsius) -> Self {
        Fahrenheit(c.0 * 9.0 / 5.0 + 32.0)
    }
}

fn main() {
    let c = Celsius(100.0);
    let f: Fahrenheit = c.clone().into(); // From 이 있어서 .into() 가 통함
    println!("{c} = {}°F", f.0);          // Display 가 {c} 를 줌
}

External links

Exercise

Money(u64) newtype 을 만들어. Debug, Clone, Copy, PartialEq 를 derive 해. $1.23 (센트를 달러로) 로 출력하게 Display 를 손으로 구현해. From<u64> for Money 를 구현해. 그다음 == 가 되고, {} 가 예쁘게 출력되고, 42u64.into()Money 를 짓는지 확인해.
Hint
기계적 trait 넷은 한 attribute 로 derive; 달러 포맷팅엔 Display 를 손으로; From<u64> 를 구현하면 .into() 가 공짜로 와. 그 조합 — 지루한 건 derive, 의미 있는 건 구현 — 이 일상 Rust 야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.