제네릭에 대해 알아보겠습니다. 제네릭은 쉽게말해 모든 데이터 타입의 상위 타입이라고 생각하시면 쉬울 것 같습니다.
struct Point<T> {
x: T,
y: T,
}
fn main() {
let integer = Point { x: 5, y: 10 };
let float = Point { x: 1.0, y: 4.0 };
}
구조체의 데이터 타입을 제네릭으로 선언했습니다. main 함수에서 두 개의 Point 구조체가 선언되었는데 두 구조체가 서로 다른 데이터 타입(정수형, 실수형) 을 가지고 있는 것을 확인하실 수 있습니다.
struct Point<T> {
x: T,
y: T,
}
fn main() {
let wont_work = Point { x: 5, y: 4.0 };
}
하지만 Point<T> 로 선언된 구조체의 구성요소는 모두 같은 데이터 타입으로 사용되어야 합니다. 그렇지 않으면 에러를 발생시킵니다.
error[E0308]: mismatched types
-->
|
7 | let wont_work = Point { x: 5, y: 4.0 };
| ^^^ expected integral variable, found
floating-point variable
|
= note: expected type `{integer}`
= note: found type `{float}`
만약 여러 개의 제네릭 제네릭 타입을 사용하고 싶다면 다음과 같이 사용할 수 있습니다.
struct Point<T, U> {
x: T,
y: U,
}
fn main() {
let both_integer = Point { x: 5, y: 10 };
let both_float = Point { x: 1.0, y: 4.0 };
let integer_and_float = Point { x: 5, y: 4.0 };
}
이전에 배웠던 열거형 Option, Result에서 사용되었던 T를 이제는 이해할 수 있을 것입니다.
enum Option<T> {
Some(T),
None,
}
enum Result<T, E> {
Ok(T),
Err(E),
}
메소드 정의 내에서 제네릭 데이터 타입 사용
메소드에서 제네릭 타입을 사용하기 위해서는 impl 뒤에 <T>를 정의 해야만 메소드를 구현하는데 제네릭 데이터타입을 사용할 수 있다는 것을 기억해야합니다.
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}
fn main() {
let p = Point { x: 5, y: 10 };
println!("p.x = {}", p.x());
}
struct Point<T, U> {
x: T,
y: U,
}
impl<T, U> Point<T, U> {
fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
Point {
x: self.x,
y: other.y,
}
}
}
fn main() {
let p1 = Point { x: 5, y: 10.4 };
let p2 = Point { x: "Hello", y: 'c'};
let p3 = p1.mixup(p2);
println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
}
'Rust' 카테고리의 다른 글
[Rust] 트레잇(Trait) (0) | 2022.05.08 |
---|---|
[Rust] 테스트 (0) | 2022.04.29 |
[Rust] 벡터 (0) | 2022.04.27 |
[Rust] 해쉬맵 (hash map) (0) | 2022.04.26 |
[Rust] 문자열 (0) | 2022.04.25 |