프로그래밍러스트 개발자 / 백엔드 개발자

러스트에서 생성자와 팩토리 메서드(예: new, with_capacity)란 무엇이며, 이를 올바르게 구현하는 방법과 초보자들이 자주 범하는 오류는 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변.

러스트는 C++/Java와 같은 특별한 생성자를 가지고 있지 않습니다. 일반적으로 생성자는 연관 함수로 구현됩니다(예: new). 중요한 특징은 다음과 같습니다:

  • 연관 함수는 트레이트나 객체와 연결되어 있지 않으며 ::를 통해 호출됩니다.
  • self 또는 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을 도입하여 생태계의 라이브러리와 코드 호환성을 높였습니다.