rust into from

agnusdei·2025년 2월 8일

Rust의 into()from() – 좌항 변환의 원리

Rust에서 into()from()타입 변환을 쉽게 하기 위한 트레이트 메서드입니다.
이 둘은 "좌항 변환(할당받는 변수의 타입에 맞춰 변환)" 을 수행하는데, 핵심 원리From<T> 트레이트입니다.


1. into()from()의 기본 개념

Rust에서 타입을 변환할 때 From<T>Into<T> 트레이트가 사용됩니다.

(1) From<T> 트레이트

  • T 타입을 Self로 변환하는 기능을 제공하는 트레이트
  • 직접 호출할 수 있음
pub trait From<T> {
    fn from(_: T) -> Self;
}

(2) Into<T> 트레이트

  • SelfT로 변환하는 기능을 제공하는 트레이트
  • From<T>가 구현되어 있으면 자동으로 Into<T>도 사용 가능
pub trait Into<T> {
    fn into(self) -> T;
}
  • Into<T>는 내부적으로 T::from(self)을 호출
  • 즉, From<T>가 구현되어 있으면 into()도 자동으로 사용 가능

2. into()from()의 차이

메서드사용 방식내부 동작
from()T::from(value)명시적으로 변환 호출
into()value.into()내부적으로 T::from(value) 호출

즉, into()는 왼쪽 타입에 맞춰 자동 변환을 수행하고, from()은 직접 호출하는 방식입니다.


3. 실제 동작 원리 – From<T>Into<T>

(1) from()을 직접 구현

struct MyNumber(i32);

impl From<i32> for MyNumber {
    fn from(num: i32) -> Self {
        MyNumber(num)
    }
}

fn main() {
    let num = 42;
    let my_num = MyNumber::from(num); // 명시적 변환
    println!("{}", my_num.0); // 42
}
  • From<i32> for MyNumber를 구현하여 i32MyNumber로 변환할 수 있음
  • MyNumber::from(num)을 호출하여 변환

(2) into()를 활용한 자동 변환

fn main() {
    let num = 42;
    let my_num: MyNumber = num.into(); // 자동 변환
    println!("{}", my_num.0); // 42
}
  • let my_num: MyNumber = num.into();
    • num.into()를 호출하면 Rust가 MyNumber::from(num)을 자동 호출
    • 즉, 왼쪽 변수 타입(MyNumber)에 맞춰 num을 변환

➡ 원리

  • into()From<T>가 구현되어 있는 경우 자동으로 from()을 호출하여 변환을 수행
  • num.into() → 내부적으로 MyNumber::from(num) 실행

4. into()와 좌항 변환 (왼쪽 타입에 맞춤)

Rust에서 into()왼쪽 타입(할당받는 변수 타입)에 맞춰 변환됩니다.

fn main() {
    let x: i32 = 10;
    let y: i64 = x.into(); // x(i32) → y(i64) 변환
    println!("{}", y);
}
  • xi32, yi64
  • i64::from(i32)가 구현되어 있어 x.into()가 가능

➡ 좌항 변환 동작 원리

  1. Rust는 let y: i64 = x.into();를 해석
  2. x.into()를 실행하는데, x의 타입(i32)에서 i64로 변환할 수 있는지 확인
  3. From<i32> for i64가 구현되어 있으므로 i64::from(x)를 호출하여 변환

5. into()from()의 활용 예제

(1) String 변환 (&str → String)

fn main() {
    let s: String = "hello".into(); // &str을 String으로 변환
    println!("{}", s);
}
  • "hello"&str 타입이지만, String을 기대하는 곳(let s: String)에 맞춰 변환됨
  • 내부적으로 String::from("hello")를 호출

(2) Box<T> 변환 (&str → Box<str>)

fn main() {
    let boxed: Box<str> = "Rust".into(); // &str을 Box<str>로 변환
    println!("{}", boxed);
}
  • "Rust"&str이지만, Box<str>로 변환 가능
  • 내부적으로 Box::new(str)를 호출하는 것과 유사한 동작

6. into()가 동작하지 않는 경우

만약 From<T>가 구현되지 않은 타입 변환을 시도하면 컴파일 오류가 발생합니다.

struct MyStruct;

fn main() {
    let x = 10;
    let y: MyStruct = x.into(); // ❌ 에러: `From<i32> for MyStruct` 없음
}
  • MyStruct에는 From<i32>가 구현되지 않았으므로 into() 사용 불가

해결 방법

  1. 직접 From<T> 구현
  2. into() 대신 as 또는 수동 변환 사용

7. 정리 – into()from() 좌항 변환 원리

from(): T::from(value)를 명시적으로 호출하여 변환
into(): 할당받는 변수(좌항)의 타입에 맞춰 자동 변환 (T::from(value) 호출)
From<T>가 구현되어 있으면 Into<T>도 자동 구현됨
Rust는 into() 호출 시 "왼쪽 변수의 타입"에 맞춰 변환할 방법이 있는지 확인
변환이 불가능하면 컴파일 오류 발생

즉, into()Rust가 좌항(왼쪽)의 타입을 기준으로 From<T>를 찾아 자동 변환하는 기능입니다!

profile
DevSecOps, Pentest, Cloud(OpenStack), Develop, Data Engineering, AI-Agent

0개의 댓글