제네릭 함수
Coddy Rust 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 27번째.
제네릭은 구조체에만 국한되지 않습니다. 어떤 타입으로든 작동하는 독립 함수를 작성할 수도 있습니다. 이는 특정 구조체에 속하지 않지만 여전히 유연해야 하는 유틸리티 함수가 필요할 때 유용합니다.
syntax는 구조체에서 본 것과 유사합니다. function 이름 뒤의 꺾쇠괄호 안에 generic 매개변수를 선언한 다음, parameters와 반환 타입에서 이를 사용하세요:
fn identity<T>(value: T) -> T {
value
}
이 identity 함수는 모든 유형의 값을 받아 변경하지 않고 반환합니다. <T>는 generic을 선언하고, value: T는 이를 parameter로 받으며, -> T는 return type을 지정합니다. 함수를 호출하면 Rust가 구체적인 유형을 추론합니다:
let num = identity(42); // T는 i32입니다
let text = identity("hello"); // T는 &str입니다
구조체에서와 마찬가지로 함수에서도 여러 제네릭 매개변수를 사용할 수 있습니다.
fn make_pair<T, U>(first: T, second: U) -> (T, U) {
(first, second)
}
let pair = make_pair(10, "ten"); // (i32, &str)를 반환합니다
제네릭 함수는 재사용 가능한 로직을 한 번 작성한 후 여러 타입에 적용할 수 있게 하여, 타입 안전성을 유지하면서 코드 중복을 줄여 줍니다.
챌린지
쉬움어떤 타입과도 작동할 수 있는 generic function을 사용하여 utility module을 만들어 보겠습니다! 특정 struct에 묶이지 않고 generic이 코드를 유연하고 재사용 가능하게 만드는 방법을 보여 주는 독립적인 function을 작성합니다.
코드를 두 파일에 걸쳐 구성합니다:
utils.rs: public generic utility function 모음을 만듭니다:wrap_in_pair<T>: single value를 받아 해당 value를 두 번 포함하는 tuple을 returns합니다:(value, value). 이를 위해 타입이Clone이어야 하므로<T: Clone>을 사용합니다.swap<T, U>: potentially different type의 두 value를 받아 reversed order로 tuple(U, T)로 returns합니다.
main.rs: utility module을 import하고 이러한 generic function이 different type에서 작동하는 모습을 보여 줍니다. 동일한 function definition이 integer, float, string을 매끄럽게 처리하는 방법을 보여 주세요.
main file에서 다음과 같이 utility function을 사용하여 보여 줍니다:
- integer(first input,
i32로 parsed)와 함께wrap_in_pair를 사용하고 두 element를 모두 출력합니다. - string(second input)과 함께
wrap_in_pair를 사용하고 두 element를 모두 출력합니다. - integer(third input,
i32로 parsed)와 string(fourth input)에swap을 사용한 다음 swapped result를 출력합니다.
출력은 다음 Format을 따라야 합니다:
Pair of ints: ({value}, {value})
Pair of strings: ({value}, {value})
Swapped: ({string}, {int})예를 들어 input이 5, hello, 42, world인 경우:
Pair of ints: (5, 5)
Pair of strings: (hello, hello)
Swapped: (world, 42)wrap_in_pair가 integer와 string 모두에서 동일하게 작동하고, swap이 완전히 different한 두 type을 처리하는 것을 확인하세요. 이것이 generic function의 유연성입니다!
네 개의 input을 받습니다: integer, string, 또 다른 integer, 또 다른 string.
REQUIRED OUTPUT FORMAT:직접 해보기
mod utils;
use std::io;
fn main() {
// 네 개의 입력을 읽습니다
let mut input1 = String::new();
io::stdin().read_line(&mut input1).expect("Failed to read line");
let num1: i32 = input1.trim().parse().expect("Invalid integer");
let mut input2 = String::new();
io::stdin().read_line(&mut input2).expect("Failed to read line");
let str1 = input2.trim().to_string();
let mut input3 = String::new();
io::stdin().read_line(&mut input3).expect("Failed to read line");
let num2: i32 = input3.trim().parse().expect("Invalid integer");
let mut input4 = String::new();
io::stdin().read_line(&mut input4).expect("Failed to read line");
let str2 = input4.trim().to_string();
// TODO: wrap_in_pair를 num1과 함께 사용하여 결과를 출력하세요
// Format: Pair of ints: ({value}, {value})
// TODO: wrap_in_pair를 str1과 함께 사용하여 결과를 출력하세요
// Format: Pair of strings: ({value}, {value})
// TODO: swap을 num2와 str2와 함께 사용한 다음, 교환된 결과를 출력하세요
// 형식: 교환됨: ({string}, {int})
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Rust 컴파일러