역사적으로 러스트의 원칙 중 하나는 타입 안전성과 실행 오류를 초래하는 암묵적인 변환의 부재였습니다. 그러나 코드의 편의성을 위해 부분적인 자동 변환은 deref coercion 및 From/Into 트레이트를 통해 구현되어, 참조, 스마트 포인터와 함께 작업을 단순화하고 범용 API를 가능하게 합니다.
문제는 자동 변환이 혼란을 초래할 수 있을 때 발생합니다. 예를 들어 &String을 &str을 예상하는 곳에 전달할 때 입니다. 이는 숨겨진 Deref::deref가 호출되고 때때로 예기치 않은 결과가 나타납니다(예: 전달되는 매개변수의 타입 변경 시). 또한 as를 통한 직접적이고 명시적인 캐스팅에 대한 질문도 있습니다.
해결책: 러스트는 컴파일러 단계에서 스마트 포인터(Box, Rc, Arc) 및 문자열(&String에서 &str, &Vec에서 &slice) 대한 deref-coercion의 엄격한 규칙을 구현합니다. 명시적 변환을 위해 From, Into, TryFrom, TryInto 및 기본 캐스트를 위한 as 트레이트가 제공됩니다. 정적 타이핑과 암묵적 변환의 제한은 오류를 방지하는 데 도움을 줍니다.
코드 예시:
fn print_text(text: &str) { println!("{}", text); } let s = String::from("Hello!"); print_text(&s); // s: String, &s: &String, 자동 변환을 통해 &str로
주요 특징:
Deref를 수동으로 구현하면 사용자 정의 타입에도 deref coercion이 작동합니까?
네, 자신의 타입에 대해 Deref 트레이트를 구현한다면, 컴파일러는 함수 서명 내에서 해당 참조를 기대하는 목표 타입으로 자동 변환할 수 있습니다.
값에 대한 deref coercion이 가능합니까?
아니요, 자동 역참조는 참조를 전달할 때만 발생하며, 오직 타입이 Deref를 구현할 때만 발생합니다.
숫자 및 enum 작업 시 as를 통한 타입 변환에 어떤 제한이 있습니까?
as는 안전성을 보장하지 않습니다: 숫자 타입 간의 변환은 오버플로우나 데이터 손실을 초래할 수 있으며, enum의 경우는 비의미적인 값으로 이어질 수 있습니다(예: 잘못된 enum 변형으로).
초보자가 &String을 받는 함수를 작성하고 &str을 직접 사용할 수 없어 text.to_string()을 모든 곳에서 호출하는 경우입니다. 이는 메모리와 성능 측면에서 비효율적입니다.
장점:
단점:
함수가 &str 타입의 인자를 받아 스트링 리터럴, &str, &String 등의 모든 타입에 호출될 수 있습니다. 불필요한 할당이 필요 없습니다.
장점:
단점: