where 절
Coddy Rust 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 42번째.
trait 바운드를 더 추가하면 함수 시그니처를 읽기 어려워질 수 있습니다. 여러 제네릭 매개변수를 사용하는 함수에서 각 매개변수가 여러 트레이트를 요구하는 경우를 생각해 보세요.
fn complex_operation<T: Display + Clone, U: Debug + Summary>(first: T, second: U) {
// ...
}
이 방식도 작동하지만, 시그니처가 점점 복잡해지고 있습니다. where 절은 매개변수 목록 뒤로 트레이트 경계를 옮겨 더 깔끔한 대안을 제공합니다:
fn complex_operation<T, U>(first: T, second: U)
where
T: Display + Clone,
U: Debug + Summary,
{
// ...
}
두 버전은 기능적으로 동일합니다. where 절은 순전히 가독성을 위한 것입니다. 각 타입의 요구 사항이 각자의 줄에 표시되므로, 각 generic 매개변수에 필요한 사항을 쉽게 훑어볼 수 있습니다.
where clause는 bounds가 복잡하거나 generic 매개변수가 많을 때 특히 유용합니다. 한눈에 function 이름과 매개변수를 확인할 수 있으며, 제약 조건은 아래에 별도로 나열됩니다. bounds가 단순한 T: Trait를 넘어설 때 대부분의 Rust 코드베이스에서 선호되는 스타일입니다.
챌린지
쉬움복잡한 trait bound를 읽기 쉽게 유지하기 위해 where clause를 사용하는 데이터 처리 시스템을 만들어 봅시다! 여러 type parameter를 사용하는 generic function을 만들고, 각 parameter에 서로 다른 trait를 요구한 다음 where 구문을 사용해 bound를 깔끔하게 정리합니다.
코드를 두 파일에 나누어 구성합니다:
processor.rs: 두 개의 public trait와 두 trait를 모두 사용하는 generic function을 Define합니다:Summarize:&self를 받고String을 반환하는summarymethod를 가진 traitValidate:&self를 받고bool을 반환하는validatemethod를 가진 trait
process_items라는 public generic function을 만듭니다.whereclause를 사용해 첫 번째 type이Clone과Summarize를 모두 implement해야 하고, 두 번째 type이Validate를 implement해야 한다고 지정합니다. function은 첫 번째 item의 요약을 출력한 다음, 두 번째 item이 유효한지 출력해야 합니다.main.rs: 필요한 trait를 implement하는 public struct 두 개를 만듭니다:Article: publictitlefield (String)를 가집니다.Article: {title}을 반환하도록Summarize를 implement하고,Clone을 derive합니다.Form: publicfilledfield (bool)를 가집니다.filled의 값을 반환하도록Validate를 implement합니다.
process_items를 호출합니다.
where clause를 사용하면 모든 bound를 angle bracket 안에 몰아넣는 것보다 function signature가 훨씬 깔끔해집니다. 각 type의 요구 사항이 각자의 줄에 표시되므로, 각 generic parameter에 무엇이 필요한지 쉽게 확인할 수 있습니다.
출력에는 요약 다음에 validation 결과가 표시되어야 합니다:
Article: {title}
Valid: {true/false}예를 들어 input이 Rust Tips와 true인 경우:
Article: Rust Tips
Valid: trueinput이 Breaking News와 false인 경우:
Article: Breaking News
Valid: false두 개의 input을 받습니다. 하나는 article title이고, 다른 하나는 form이 filled되었는지 여부입니다(bool로 parse).
직접 해보기
mod processor;
use processor::{Summarize, Validate, process_items};
use std::io;
// TODO: 공개 title 필드(String)를 가진 공개 구조체 Article을 정의하세요
// Article에 Clone을 derive하세요
// TODO: Article에 Summarize를 구현하세요
// summary 메서드는 "Article: {title}"을 반환해야 합니다
// TODO: 공개 filled 필드(bool)를 가진 공개 구조체 Form을 정의하세요
// TODO: Form에 Validate를 구현하세요
// validate 메서드는 filled의 값을 반환해야 합니다
fn main() {
let mut title = String::new();
io::stdin().read_line(&mut title).expect("Failed to read line");
let title = title.trim().to_string();
let mut filled_input = String::new();
io::stdin().read_line(&mut filled_input).expect("Failed to read line");
let filled: bool = filled_input.trim().parse().expect("Failed to parse bool");
// TODO: 주어진 title로 Article을 생성하세요
// TODO: 주어진 filled 값으로 Form을 생성하세요
// TODO: article과 form으로 process_items를 호출하세요
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Rust 컴파일러