녹 제네릭
7129 단어 rustgenericsabstractprogramming
우리가 제네릭을 사용하는 것:-
추상 유형: i32 또는 float와 같은 명시적 유형을 작성하는 대신 다른 코드를 작성하여 다른 유형에 대한 제네릭을 사용할 수 있습니다
유연성 추가: 동일한 코드로 다양한 데이터 유형을 사용할 수 있습니다.
코드 중복 감소: 두 가지 유형에 대해 동일한 코드 또는 둘 다를 가질 수 있습니다.
런타임 비용 없음: 개체 특성과 달리 제네릭에는 런타임 비용이 없습니다. 컴파일러는 컴파일 시간 동안 백그라운드에서 다양한 유형을 생성합니다.
시작하자
일반적으로 제네릭 유형 매개변수는
<T>
로 표시됩니다. 그러나 당신은 무엇이든 자유롭게 사용할 수 있습니다.구조체
1. 단일 자리 표시자 유형
자리 표시자/제네릭 유형으로 구조체를 정의합니다.
struct Point<T> {
x: T,
y: T,
}
이것을 i32에 사용해 봅시다.
pub fn main() {
let i32_point = Point { x: 45, y: 90 };
println!("x is {} and y is {}", i32_point.x, i32_point.y);
}
i32_point를 마우스로 가리키면 변수 유형이 Point i32 i32임을 알 수 있습니다. 그러나 제한되지 않습니다. x와 y 모두에 부동 소수점을 사용할 수도 있지만 동일해야 합니다.
그렇다면 두 필드 x와 y에 대해 서로 다른 유형을 어떻게 사용할 수 있습니까?
두 자리 표시자를 사용하여 수행할 수 있습니다.
2. 두 자리 표시자
구조체 정의
struct TwoPoint<T, U> {
x: T,
y: U,
}
테스트하자
pub fn main() {
let explicit_point = TwoPoint { x: 9, y: 90.3 };
println!(
"explicit_point x is {} and y is {}",
explicit_point.x, explicit_point.y
);
}
유사하게 우리는 x와 y, 심지어 벡터에 대해 두 가지 다른 데이터 유형을 사용할 수 있습니다.
열거형
1. 열거형 제네릭
통과, 실패 또는 대기 여부에 관계없이 결과를 저장할 결과 열거형을 만듭니다.
#[derive(Debug)]
enum Result<T> {
Passed(T),
Failed(T),
Pending,
}
모든 프리미티브에 디버그 기능/특성이 포함되어 있기 때문에 열거형이 프리미티브가 아니므로
Debug
특성을 사용했습니다.테스트
pub fn main() {
let result = Result::Passed(43);
match result {
Result::Passed(a) => println!("Student Passed with {}", a),
Result::Failed(b) => println!("Student Failed with {}", b),
Result::Pending => println!("Student result is pending"),
}
}
위의 경우와 같이 Passed 및 Failed에 대해 서로 다른 제네릭 유형을 사용할 수 있습니다.
2. 제네릭과 함께 구조체 및 열거형 사용
우리는 위의 예에서 Result 열거형을 사용하고 있습니다.
struct Student<T> {
name: String,
roll_no: T,
result: Result<T>,
}
그것을 사용하자
pub fn main() {
let student = Student {
name: "Praveen".to_string(),
roll_no: 78,
result: Result::Passed(98),
};
match student.result {
Result::Passed(a) => println!("Student Passed with {}", a),
Result::Failed(b) => println!("Student Failed with {}", b),
Result::Pending => println!("Student result is pending"),
}
}
제네릭이 있는 함수
1. 단일 일반 유형 매개변수와 단일 특성을 가진 함수
기능 정의
fn custom_add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
a + b
}
여기서 Output=T는
+
또는 -
결과가 동일해야 함을 보장합니다. 두 개의 원자를 추가하면 분자(T+T=U
)가 되는 것처럼 원하는 경우 다를 수 있습니다.let a = 4;
let b = 5;
println!("sum of {} and {} is {}", a, b, custom_add(a, b));
2. 단일 일반 유형 매개변수와 여러 특성을 가진 함수
fn custom_add_sub<T: std::ops::Add<Output = T> + std::ops::Sub<Output = T> + std::fmt::Debug>(
a: T,
b: T,
) -> T {
// Debug trait is needed for this print statement
println!("{:?} {:?}", a, b);
a + b
}
유형 사용
pub fn main() {
println!("sub of {} and {} is {}", a, b, custom_add_sub(a, b));
}
나는 지금 당신이 쉽다는 것을 압니다.
3.여러 일반 유형 매개변수와 여러 특성 및 where 키워드가 포함된 함수
// using the where to define a generic type
fn custom_add_sub_mul<T, E>(a: T, b: T, c: E) -> T
where
T: std::ops::Mul<Output = T> + std::ops::Add<Output = T> + std::ops::Sub<Output = T>,
E: std::fmt::Debug,
{
println!("{:?}", c);
a * b
}
where
키워드는 코드를 더 명확하게 만듭니다. 코드 실행 방식에는 영향을 미치지 않습니다.pub fn main() {
println!("mul of {} and {} is {}", a, b, custom_add_sub_mul(a, b, b));
}
4. 커스텀 트레이트가 있는 기능
미리 정의된 특성을 사용하는 대신 원하는 대로 사용자 지정 특성을 사용할 수 있습니다.
trait SomeCustomTrait {
fn bla_bla(&self, a: &str, b: &str) -> String;
}
#[derive(Debug)]
struct TestStruct {
something: i32,
}
impl SomeCustomTrait for TestStruct {
fn bla_bla(&self, a: &str, b: &str) -> String {
self.something.to_string() + "-" + a + "-" + b
}
}
fn do_this<T>(some_var: &T) -> String
where
T: SomeCustomTrait + std::fmt::Debug,
{
println!("{:?}", some_var);
some_var.bla_bla("first", "second")
}
함수에서 우리는 디버그와 함께 우리의
SomeCustomTrait
를 사용했습니다. 더 추가할 수도 있습니다.pub fn main() {
let test = TestStruct { something: 1000 };
let result = do_this(&test);
}
제네릭 구현
struct ImplStruct<T, U> {
field1: T,
field2: U,
}
impl<T, U> ImplStruct<T, U>
where
T: std::fmt::Debug,
U: std::fmt::Debug,
{
fn log_something(&self) {
println!("{:?} {:?}", self.field1, self.field2);
}
}
여기에서 제네릭 유형이 구조체 대신
impl block
에 정의되어 있음을 알 수 있지만 두 블록 모두에서 정의할 수 있지만 Impl 블록은 필수입니다.pub fn main() {
let impl_test = ImplStruct{
field1:5.6,
field2:vec![1,2,3],
};
impl_test.log_something();
그래서 우리는 Rust Generics의 기초를 다루었지만 Generics로 더 많은 것을 할 수 있습니다.
자원
소스 코드
RustyRustLessons Generics
해피해킹
러스타시안!
Reference
이 문제에 관하여(녹 제네릭), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/chaudharypraveen98/rust-generics-c11텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)