파생 특성 사용
사용자 지정 형식을 실제로 사용하는 것은 약간 어려울 수 있습니다. 이 간단한 Point
구조체를 다른 Point
인스턴스와 비교하거나 터미널에 표시할 수 없습니다. 이러한 어려움 때문에 derive 특성을 사용하여 구조체에 대해 자동으로 새 항목이 생성되도록 할 수 있습니다.
제네릭 형식의 단점
다음 코드 예제를 살펴보세요.
struct Point {
x: i32,
y: i32,
}
fn main() {
let p1 = Point { x: 1, y: 2 };
let p2 = Point { x: 4, y: -3 };
if p1 == p2 { // can't compare two Point values!
println!("equal!");
} else {
println!("not equal!");
}
println!("{}", p1); // can't print using the '{}' format specifier!
println!("{:?}", p1); // can't print using the '{:?}' format specifier!
}
위의 코드는 3가지 이유로 실패합니다. 다음 출력을 참조하세요.
error[E0277]: `Point` doesn't implement `std::fmt::Display`
--> src/main.rs:10:20
|
10 | println!("{}", p1);
| ^^ `Point` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `Point`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: required by `std::fmt::Display::fmt`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `Point` doesn't implement `Debug`
--> src/main.rs:11:22
|
11 | println!("{:?}", p1);
| ^^ `Point` cannot be formatted using `{:?}`
|
= help: the trait `Debug` is not implemented for `Point`
= note: add `#[derive(Debug)]` or manually implement `Debug`
= note: required by `std::fmt::Debug::fmt`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0369]: binary operation `==` cannot be applied to type `Point`
--> src/main.rs:13:11
|
13 | if p1 == p2 {
| -- ^^ -- Point
| |
| Point
|
= note: an implementation of `std::cmp::PartialEq` might be missing for `Point`
error: aborting due to 3 previous errors#+end_example
Point
형식에서는 다음 특성을 구현하지 않기 때문에 이 코드는 컴파일되지 않습니다.
{:?}
형식 지정자를 사용하여 형식을 지정할 수 있도록 하는Debug
특성은 프로그래머 지향 디버깅 컨텍스트에서 사용됩니다.{}
형식 지정자를 사용하여 형식을 지정할 수 있도록 하는Display
특성은Debug
와 비슷합니다. 그러나Display
는 사용자에게 표시되는 출력에 보다 적합합니다.- 구현자가 같은지 비교할 수 있도록 하는
PartialEq
특성
파생 사용
다행히 각 필드에서 #[derive(Trait)]
특성을 구현하는 경우 해당 특성을 사용하여 Rust 컴파일러에서 Debug
및 PartialEq
특성을 자동으로 구현할 수 있습니다.
#[derive(Debug, PartialEq)]
struct Point {
x: i32,
y: i32,
}
Rust의 표준 라이브러리는 최종 사용자를 위한 것이므로 Display
특성에 대한 자동 구현을 제공하지 않습니다. 따라서 코드는 여전히 컴파일되지 못합니다. 그러나 해당 줄을 주석으로 처리하는 경우 이제 이 코드는 다음과 같은 출력을 생성합니다.
not equal!
Point { x: 1, y: 2 }
그렇지만 형식에 대한 Display
특성을 직접 구현할 수 있습니다.
use std::fmt;
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
이제 코드가 컴파일됩니다.
not equal!
(1, 2)
Point { x: 1, y: 2 }
이 Rust Playground 링크에서 이 예제의 코드를 확인하세요.