1. From : 한 자료형을 다른 자료형으로 변환하는 로직을 정의
2. Into : From 의 역방향으로 자료형을 변환
// 러스트는 타입에 관한 엄격한 안정성을 보장한다.
// 그래서 타입을 변환할 때는 명시적으로 변환을 해줘야 한다.
// From 은 한 자료형을 다른 자료형으로 변환하는 로직을 정의할 때 사용
// Into는 From을 통해 변환된 자료형을 사용.
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
// Point 구조체를 (i32, i32) 튜플로 변환하는 From trait 구현
impl From<(i32, i32)> for Point {
fn from(tuple: (i32, i32)) -> Self {
Point { x: tuple.0, y: tuple.1 }
}
}
fn main() {
let tuple = (1, 2);
// 주어진 tuple을 바탕으로 Point객체를 생성
let pt: Point = Point::from(tuple);
println!("Point::from = {:?}", pt);
// tuple을 기반으로 point를 생성합니다. 이때 Point::from이 호출
let pt: Point = tuple.into();
println!("tuple.into = {:?}", pt);
}
/*실행결과
Point::from = Point { x: 1, y: 2 }
tuple.into = Point { x: 1, y: 2 }
*/
3. AsRef : 객체를 참조값으로 변환
// AsRef 트레잇은 어떤 타입을 다른 타입으로 변환할 수 있는 방법
// 이 트레잇을 구현하면, 해당 타입을 다른 타입으로 쉽게 변환
// 예를 들어, String을 &str로 변환하거나, Vec<T>를 &[T]로 변환
// 이 메서드는 AsRef 트레잇을 구현한 타입의 인스턴스에서 호출
struct Person {
name: String,
age: u32,
}
impl AsRef<str> for Person {
// Person의 name을 str형태로 참조할 수 있습니다.
fn as_ref(&self) -> &str {
&self.name
}
}
fn greet_person<P: AsRef<str>>(person: P) {
println!("안녕! {}!", person.as_ref());
}
fn main() {
let person = Person { name: String::from("루나"), age: 30 };
// Person 구조체에 AsRef<str>를 구현했기 때문에,
// greet_person 함수는 Person을 인자로 받아 사용할 수 있습니다.
greet_person(person); //안녕! 루나!
// 물론, String과 &str도 여전히 함수의 인자로 사용할 수 있습니다.
let name_string = String::from("러스트");
greet_person(name_string); //안녕! 러스트!
greet_person("하이!"); //안녕! 하이!!
}
/*실행결과
안녕! 루나!
안녕! 러스트!
안녕! 하이!!
*/
4. AsMut : 객체를 수정 가능한 참조로 변환
// AsMut 는 객체를 수정 가능할 참조로 바꾸는 트레잇이다.
// AsMut 트레잇을 구현한 타입은 &mut T로 변환할 수 있다.
struct Person {
name: String,
age: u32,
}
// AsMut 트레잇을 구현하여 name 필드에 대한 가변 참조를 제공한다.
// AsMut 트레잇을 구현하면, &mut T로 변환할 수 있다.
impl AsMut<String> for Person {
fn as_mut(&mut self) -> &mut String {
&mut self.name
}
}
// name_change 함수는 AsMut 트레잇을 구현한 타입에 대해
// name 필드의 값을 변경하는 기능을 제공한다.
// 이 함수는 person 매개변수로 전달된 객체의 name 필드를
// 가변 참조로 가져와서 새로운 이름으로 변경한다.
fn name_change<P: AsMut<String>>(person: &mut P, new_name: &str) {
let name = person.as_mut();
name.clear();
name.push_str(new_name);
}
fn main() {
let mut person = Person {
name: String::from("루나"),
age: 10
};
println!("변경 전: {}", person.name); //변경 전: 루나
name_change(&mut person, "러스트");
println!("변경 후: {}", person.name); //변경 후: 러스트
}
/*실행 결과
변경 전: 루나
변경 후: 러스트
*/