100 Exercises To Learn Rust - 4.1 trait 풀기

Trait

Trait은 rust가 인터페이스를 정의하는 방식이다.

 

구조체와 같이 새로운 타입을 만들고 나면, impl 키워드를 이용해 해당 타입에서 동작할 메서드를 정의할 수 있다.

 

trait은 메서드처럼 활용하기 위해서는 타입에다 구현해야 하는 건 동일하지만, 그렇다고 trait이 해당 메서드에 종속적인 건 아니다. 다른 타입도 똑같은 trait을 활용할 수 있다. 다만 구체적인 구현만 다를 뿐이다.

풀이

// `is_even` 메서드를 갖고, `self`가 짝수이면 `true`를, 홀수이면 `false`를 반환하는
// `IsEven` 트레이트를 정의하세요.
// 이후 `u32`와 `i32`에 대해 구현하세요.

trait IsEven {
    fn is_even(&self) -> bool;
}

impl IsEven for u32 {
    fn is_even(&self) -> bool {
        (self % 2) == 0
    }
}
impl IsEven for i32 {
    fn is_even(&self) -> bool {
        (self % 2) == 0
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_u32_is_even() {
        assert!(42u32.is_even());
        assert!(!43u32.is_even());
    }

    #[test]
    fn test_i32_is_even() {
        assert!(42i32.is_even());
        assert!(!43i32.is_even());
        assert!(0i32.is_even());
        assert!(!(-1i32).is_even());
    }
}

 

트레이트를 내용 없이 정의한 다음, 각 타입마다 따로 구현했다.

 

self를 참조 없이 사용하게 되면 컴파일 타임에 self의 타입을 알 수 없다는 오류가 발생한다.

참조를 사용하면 포인터로 항상 크기를 알 수 있기 떄문에 컴파일 가능하다.