Rust From trait

wangki·2025년 1월 12일
0

Rust

목록 보기
7/54

글 작성 이유

rust로 코드를 작성하며 ? 연산자를 통해서 편리하게 에러 핸들링을 할 수 있다.
Error 타입이 달라도 컴파일 에러가 발생하지 않는 것을 보고 찾아보니 From trait가 구현이 되어있으면 자동으로 변환이 이루어진다고 한다.
From trait에 대해서 자세히 알아보기 위해서 작성해본다.

From trait 란?

하나의 타입을 다른 타입으로 변환하는 기능을 제공하는 것이다.

코드로 예시를 보면

#[derive(Clone, Copy)]
struct A {
    inner : i32
}

struct B {
    inner : i32
}

impl From<A> for B {
    fn from(value: A) -> Self {
        B { inner : value.inner}
    }
}

fn main() {
    let a = A { inner : 10};
    
    // 명시적 변환
    let explicit_b = B::from(a);
 
    // 암묵적 변환
    let implicit_b : B = a.into();
 
    println!("명시적으로 변환된 B : {}", explicit_b.inner);
    println!("암묵적으로 변환된 B : {}", implicit_b.inner);
 }

구조체 AB를 정의하고 From trait를 B에 대해서 구현했다.
A 타입을 B로 명시적, 암묵적으로 변환이 가능하도록 한다.

그럼 into는 어디서 나온 메서드인지 궁금할 수 있다.

std공식문서를 보면

One should avoid implementing Into and implement From instead. Implementing From automatically provides one with an implementation of Into thanks to the blanket implementation in the standard library.

From trait를 구현하면 자동으로 into 구현이 제공된다고 나와있다.

반환 타입 자동 변환

입출력 표준 에러타입인 io Error와 ParseIntError가 동시에 발생할 수 있는 함수에서 CustomError를 통해서 처리하는 방법을 코드로 알아보겠다.

use std::io;
use std::num::ParseIntError;

 #[derive(Debug)]
 enum CustomError {
    IoError(io::Error),
    ParseError(ParseIntError),
 }

먼저 From trait를 구현하지 않은 경우에 대해서 살펴본다.


fn read_and_parse(filename : &str) -> Result<i32, CustomError> {
    match std::fs::read_to_string(filename) {
        Ok(content) => {
            match content.trim().parse() {
                Ok(number) => {
                    Ok(number)
                },
                Err(e) => {
                    Err(CustomError::ParseError(e))
                }
            }
        },
        Err(e) => {
            Err(CustomError::IoError(e))
        }
    }
}

두번의 match를 통해서 로직을 작성했고, Err를 반환 시 CustomError객체를 Err로 래핑하여 반환하였다.

그럼 이제 From 트레이트를 구현하여 read_and_parse를 재작성 해보겠다.

 // From trait 

 impl From<io::Error> for CustomError {
    fn from(err : io::Error) -> Self {
        CustomError::IoError(err)
    }
 }

 impl From<ParseIntError> for CustomError {
    fn from(err : ParseIntError) -> Self {
        CustomError::ParseError(err)
    }
 }
// read_and_parse 재작성
fn read_and_parse(filename : &str) -> Result<i32, CustomError> {
    let content = std::fs::read_to_string(filename)?;
    let number : i32 = content.trim().parse()?;

    Ok(number)
}

? 연산자를 이용하여 Result의 값이 Err이면 io::ErrorParseIntErrorCustomError로 자동 변환되어 반환되는 모습을 볼 수 있다.

코드를 간편하게 작성할 수 있게 도움을 준다.

결론

From trait를 구현하게 되면 자동변환으로 편리함을 제공받을 수 있다.

감사합니다.

0개의 댓글