러스트는 C++/Java와 같은 특별한 생성자를 가지고 있지 않습니다. 일반적으로 생성자는 연관 함수로 구현됩니다(예: new). 중요한 특징은 다음과 같습니다:
::를 통해 호출됩니다.Result<Self, E>를 반환할 수 있어 실패 가능한 생성자에 유용합니다.with_capacity, from_str, 사용자 정의 옵션).기본 생성자 예:
struct Point { x: i32, y: i32 } impl Point { pub fn new(x: i32, y: i32) -> Self { Point { x, y } } }
실패 가능한 생성자 예:
impl Point { pub fn try_new(x: i32, y: i32) -> Result<Self, String> { if x < 0 || y < 0 { Err("좌표는 음수가 될 수 없습니다".to_string()) } else { Ok(Point { x, y }) } } }
생성자에 사용할 함수의 유형은 무엇이어야 하는가: 일반 함수, 메서드 또는 연관 함수, 그 이유는?
많은 사람들이 "메서드"라고 답합니다. 그러나 러스트에서 생성자는 오직 연관 함수만 가능합니다(자기 자신이 없음). 왜냐하면 인스턴스가 아직 존재하지 않기 때문에 일반 메서드를 호출할 수 없기 때문입니다.
struct Foo; impl Foo { // 연관 함수, 메서드 아님 pub fn new() -> Self { Foo } }
이야기
프로그래머가 생성자를 메서드로 구현했습니다:
impl Point { pub fn make(&self, x: i32, y: i32) -> Self { ... } }이는 비논리적이며 혼란을 초래합니다: 객체를 만들기 위해서는 아직 존재하지 않는 객체가 필요합니다! 개발자는 이 메서드를 어떻게 호출해야 할지 곤란해졌습니다. 정적 함수로 수정했습니다.
이야기
고전적인 실수: 실패 가능한 생성자에 대해 경고 없이 Option<Self>를 반환하여 연쇄 오류를 건너뛰었습니다. Result<Self, E>를 반환하게 되면서 오류를 보다 명시적으로 출력할 수 있게 되었습니다.
이야기
from_parts,from_str형식의 팩토리를 From/FromStr 트레이트를 사용하지 않고 구현했습니다. 결과적으로 표준 변환 메커니즘이 작동하지 않았습니다(예:str.parse::<MyType>()). 오류를 발견한 후 FromStr을 도입하여 생태계의 라이브러리와 코드 호환성을 높였습니다.