2019-05-12

[Rust] 타입 변환하기

Rust에서 타입 변환은 특별한 것이 아니다. 그저 단순히 하나의 값을 소유권을 받아 다른 타입의 값을 반환하는 함수다. 따라서 자신이 원하는 이름으로 아무 함수나 만들면 된다. 하지만 가독성을 위해 as_, to_, into_를 prefix로 사용하는 method를 만들거나, from_가 prefix로 붙는 생성자를 만들어 converting constructor처럼 만들어 사용한다.

From

타입 변환을 보다 일반적으로 구현하고 싶으면 From 트레잇을 구현하면 된다. 예를 들어 A라는 타입을 B라는 타입으로 변환하고 싶을 때는, B 타입에 From<A>를 구현하는 것이다. From 트레잇은 from이라는 associated function을 제공하기 때문에 A타입의 변수 aB타입으로 변환시킬 경우 From::from(a)이라는 식으로 사용한다. 만약, 컴파일러가 타입 추론을 못 해주는 경우 변환할 타입을 명시적으로 적어 B::from(a)이라는 식으로 사용하면 된다.

Into

From 트레잇은 변환될 타입의 associated function을 제공한다. 덕분에 변환될 타입을 명시할 수 있다. 이는 From 트레잇의 장점이지만, 구체적인 타입을 많이 적을수록 코드의 범용성을 떨어뜨린다. 범용성을 떨어뜨리지 않기 위해 From::from(a)와 같은 식으로 사용할 수도 있지만, from은 associated function이기 때문에 a.from() 같은 식으로 호출할 수는 없다. 이 경우 Into 트레잇이 유용하게 사용된다.

From 트레잇이 변환될 타입의 associated function을 제공하는 반면, Into into라는 method를 제공한다. 따라서 A 타입에서 B로 가는 Into 트레잇을 구현하고 있으면, A 타입인 변수 a가 있을 때, a.into() 같은 식으로 변환 함수를 호출할 수 있다. 물론, A::into(a)Into::into(a) 같은 식으로 호출하는 것이 문법적으로 틀린 것은 아니지만, 굳이 이렇게 의미 없이 긴 코드를 사용할 이유는 없다.

실패할 수 있는 타입 변환

위에서 말 한 From이나 Into는 실패하지 않는 타입 변환을 일반화하기 위한 트레잇이다. 하지만 어떤 변환의 경우 실패할 수도 있다. 이런 경우 TryFromTryInto를 사용해야 한다. 예를 들면 i128i32로 변환하는 것 같이 더 작은 타입으로 변환하는 함수는 실패할 수 있다. 이런 변환은 실패하면 TryFromIntError를 반환하는 TryFrom을 통해 구현된다.

TryFromTryInto의 관계는 FromInto의 관계와 같다. TryFromtry_from이라는 associated function을 제공하고, TryIntotry_into라는 method를 제공한다.

FromInto의 관계

FromInto는 method를 제공하는가 associated function을 제공하는가의 차이일 뿐 둘 사이의 동작이 다르면 안 된다. 사실 다른 동작을 구현할 수 없다. A 타입의 From<B>B 타입의 Into<A>를 같이 구현하려고 하면, 다음과 같은 에러가 나온다.

error[E0119]: conflicting implementations of trait `std::convert::Into<A>` for type `B`:
From을 구현하는 타입은 자동으로 Into도 구현하기 때문이다. 즉, 타입 변환 함수를 원하면 From만 구현하면 된다. Into를 구현하여 into 함수만 존재하는 타입을 만드는 것도 가능하지만, 이런 타입은 필요 없다. 사용자는 Into 트레잇을 구현하는 타입은, From 트레잇도 구현했을 것이라고 생각한다. 따라서 into 함수가 필요한 경우 From 트레잇을 구현하는 것이 좋다.

사실 Into를 구현해야 하는 케이스가 단 하나 있다. 만약 변환된 타입이 generic 타입이고, 현재 crate에서 선언된 타입이 아닐 때다. 이 경우 From을 구현하는 코드는 컴파일되지 않기 때문에, Into를 구현해야 한다. 이것이 유일하게 From이 아닌 Into를 구현해야 하는 경우다. 이는 TryFromTryInto에서도 마찬가지다.

댓글 3개:

  1. 안녕하세요.
    개인적으로 Rust에 관심이 많은 학생입니다.
    Rust라는 언어의 문제점이 부족한 라이브러리라고들 하는데 2019년 현재는 상황이 어떤지 알 수 있을까요? 상황이 계속해서 좋아지고 있는걸까요?

    답글삭제
    답글
    1. 안녕하세요. 답변이 늦어져서 죄송합니다.
      라이브러리가 부족하다는 말을 어디서 들으셨는지 모르겠지만, 하려고 하는 일과 분야에 따라 다르게 느껴질 것 같네요.
      러스트 개발자들 중 많은 사람들이 시스템프로그래밍, 멀티스레딩, 네트워크 프로그래밍, 암호학 등에 관심 있는 사람들이라서 이런 분야에서 사용할 때 필요한 라이브러리가 부족하다고 느끼실 일은 없으실 것입니다.

      삭제