[Rust] 타입 변환하기
Rust에서 타입 변환은 특별한 것이 아니다. 그저 단순히 하나의 값을 소유권을 받아 다른 타입의 값을 반환하는 함수다. 따라서 자신이 원하는 이름으로 아무 함수나 만들면 된다. 하지만 가독성을 위해 as_
, to_
, into_
를 prefix로 사용하는 method를 만들거나, from_
가 prefix로 붙는 생성자를 만들어 converting constructor처럼 만들어 사용한다.
From
타입 변환을 보다 일반적으로 구현하고 싶으면 From
트레잇을 구현하면 된다. 예를 들어 A
라는 타입을 B
라는 타입으로 변환하고 싶을 때는, B
타입에 From<A>
를 구현하는 것이다. From
트레잇은 from
이라는 associated function을 제공하기 때문에 A
타입의 변수 a
를 B
타입으로 변환시킬 경우 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
는 실패하지 않는 타입 변환을 일반화하기 위한 트레잇이다. 하지만 어떤 변환의 경우 실패할 수도 있다. 이런 경우 TryFrom
과 TryInto
를 사용해야 한다. 예를 들면 i128
을 i32
로 변환하는 것 같이 더 작은 타입으로 변환하는 함수는 실패할 수 있다. 이런 변환은 실패하면 TryFromIntError
를 반환하는 TryFrom
을 통해 구현된다.
TryFrom
과 TryInto
의 관계는 From
과 Into
의 관계와 같다. TryFrom
은 try_from
이라는 associated function을 제공하고, TryInto
는 try_into
라는 method를 제공한다.
From
과 Into
의 관계
From
과 Into
는 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
를 구현해야 하는 경우다. 이는 TryFrom
과 TryInto
에서도 마찬가지다.
안녕하세요.
답글삭제개인적으로 Rust에 관심이 많은 학생입니다.
Rust라는 언어의 문제점이 부족한 라이브러리라고들 하는데 2019년 현재는 상황이 어떤지 알 수 있을까요? 상황이 계속해서 좋아지고 있는걸까요?
안녕하세요. 답변이 늦어져서 죄송합니다.
삭제라이브러리가 부족하다는 말을 어디서 들으셨는지 모르겠지만, 하려고 하는 일과 분야에 따라 다르게 느껴질 것 같네요.
러스트 개발자들 중 많은 사람들이 시스템프로그래밍, 멀티스레딩, 네트워크 프로그래밍, 암호학 등에 관심 있는 사람들이라서 이런 분야에서 사용할 때 필요한 라이브러리가 부족하다고 느끼실 일은 없으실 것입니다.
감사합니다. ^^
삭제