Hacker News 의견
  • 글이 좋았음. 다만 PizzaOrder 예시는 구조가 너무 많은 관심사를 한 struct에 몰아넣은 느낌임
    ordered_at을 비교에서 제외하려는 목적이라면, PizzaDetailsPizzaOrder 두 개의 struct로 분리하는 게 더 낫다고 생각함
    이렇게 하면 PartialEq 구현 시 details만 비교하도록 명확히 할 수 있음

    • 좋은 지적임. 하지만 여전히 논리적으로는 잘못된 모델링이라고 생각함
      주문 시간이 다르면 같은 주문이 아니므로, 타입 수준에서 같다고 정의하는 건 위험함
      PizzaDetailsPartialEq을 두는 건 괜찮지만, 주문 비교 로직은 별도의 비즈니스 함수로 두는 게 맞음
    • 구조를 분리하는 접근은 좋지만, PizzaDetails를 수정할 때 그 변경이 피자 중복 제거 로직에 영향을 줄 수 있다는 점이 문제임
      struct는 단순히 데이터를 묶는 용도로만 쓰는 게 이상적임
      변경이 다른 곳에 영향을 미치지 않도록, PizzaComparatorPizzaFlavor 같은 별도 타입을 두는 방법도 고려할 수 있음
      Protobuf처럼 필드에 {important_to_flavour=true} 같은 필드 주석을 둘 수 있다면 좋겠음
    • 단순히 다른 비교 방식을 위해 구조를 분리하는 건 일반화되지 않음
      예를 들어 문자열을 대소문자 구분 없이 비교하려면 어떻게 분리할 수 있겠음?
  • Rust에서 정말 멋진 점은 방어적 프로그래밍이 필요 없는 경우가 많다는 것임
    소유권이나 참조 규칙 덕분에, 특정 객체에 대한 접근이 프로그램 전체에서 유일함을 보장받을 수 있음
    참조는 null이 될 수 없고, 스마트 포인터도 null이 될 수 없음
    self의 소유권을 넘기면 이후 메서드 호출이 불가능하다는 것도 타입 시스템이 보장함
    덕분에 스레드 안전성, 수명, 복제 가능성 등이 컴파일 타임에 전역적으로 검증

    • 나도 Rust의 진짜 장점이 “신경 쓰지 않아도 되는 것들”에 있다고 생각함
      다른 언어에서는 함수형 스타일로 불변성을 유지해야 얻는 이점을 Rust는 타입 시스템으로 강제함
    • 하지만 이 댓글은 원문 기사와는 관련이 없어 보임
      기사 주제는 borrow checker로도 잡히지 않는 논리적 버그였음
    • 기사 내용은 주로 프로그램을 반복적으로 개선할 때 논리적 실수를 피하는 코딩 패턴에 초점을 맞췄음
  • 배열이나 벡터에 직접 인덱싱하는 건 피하는 게 현명하다고 느낌
    Cloudflare의 unwrap 사고가 있었던 날, 나도 슬라이스가 벡터 끝을 넘어가는 버그를 발견했음
    이후 이터레이터 기반 접근으로 바꾸고 훨씬 안전하게 느껴짐

    • unwrap 사고를 “사고”로 볼 필요는 없다고 생각함
      Rust의 unwrap은 C의 assert와 같음. 실패하면 문제를 알려주는 역할을 하는 것뿐임
      Rust에서도 버그는 여전히 작성할 수 있음
    • 결국 같은 문제임. Rust 진영에서 C를 버리자고 하지만, C에서도 인덱스 대신 핸들을 쓰는 게 일반적임
  • Rust 개발자들이 방어해야 할 습관 중 하나는 불필요한 crate 의존성을 추가하는 것임
    Rust는 이런 습관을 장려하는 경향이 있음. 예를 들어 Rust Book에서 rand crate를 기본 예시로 쓰는 것도 그런 분위기를 만듦
    물론 암호 관련 패키지를 쉽게 교체할 수 있게 한 전략적 선택이긴 하지만, 여전히 습관화되는 건 문제임

    • 나도 그 예시 때문에 Rust에 처음엔 거부감이 있었음
      하지만 나중엔 그 의도를 이해하고 생각이 바뀌었음
  • 부분 동등성 구현이 흥미로웠음
    또 하나 궁금한 건 불리언 매개변수를 피할 때 enum을 쓰는 방법임
    나는 bool을 감싼 struct를 쓰는데, 이걸 일반 bool처럼 다루지 못하는 게 아쉬움
    enum을 bool처럼 쓸 수 있는 방법이 있을까 궁금함

    • 나도 거의 항상 enum + match! 를 선호함
      필요한 로직을 Trait으로 묶거나, impl <Enum> 블록에 공통 메서드를 추가하는 식으로 처리함
      이렇게 하면 가독성도 좋고, 각 멤버별 동작을 명확히 정의할 수 있음
    • impl Deref 같은 걸 써볼 수도 있겠지만, 좋은 아이디어인지는 잘 모르겠음
  • 첫 번째 예시의 match 구문은 너무 과한 느낌임
    Vec.first()Vec.iter().nth(0)이 더 명확하고 의도에 맞음

    • 나도 동의함. match를 쓰면 오히려 문제보다 복잡한 해결책이 됨
      if를 제거할 수 있다면 match도 제거할 수 있으니, 안전성 측면에서 차이가 없음
      first()가 훨씬 간결하고 명확함
    • 같은 동작을 더 간단히 표현하려면 itertools의 exactly_one을 쓸 수도 있음
    • 다만 match는 “요소가 하나 이상일 때”의 경우도 처리하도록 유도한다는 점에서 의미가 있음
      즉, 검사와 의존 코드의 분리를 피하라는 원칙을 드러냄
  • 이런 글을 읽을 때마다, 왜 코드 패턴을 모니터링하는 전담 팀이 없는지 궁금해짐
    SOC나 QA처럼 코드베이스의 패턴을 장기적으로 관찰하는 팀이 있으면 좋겠음
    자동화된 코드 스멜 탐지 도구로는 한계가 있음

    • 우리 회사(약 300명 규모)에는 이런 역할의 기술 부채 전담팀이 있음
      린트 규칙 관리, 문서화, 개발자 교육, 공통 라이브러리 유지보수 등을 담당함
      여러 팀이 같은 문제를 반복하면, 이를 통합할 수 있는 핵심 API를 설계함
    • 대형 기술 기업에는 대부분 이런 팀이 존재함
      다만 코드가 수백만 줄이면 관리가 매우 어렵다는 게 현실임
  • 이런 좋은 코딩 패턴을 팀 내에서 어떻게 장려할 수 있을지 고민임
    코드 리뷰 중에는 “스타일 논쟁”으로 번져 비생산적일 때가 많음
    그런데 신기하게도 린터가 경고를 띄우면 그런 논쟁이 거의 사라짐

  • TryFrom 트레이트가 1.34 버전에 추가된 게 정말 유용했음
    아마 unwrap_or_else()를 쓰던 코드는 그 이전 시기의 잔재일 가능성이 큼
    From 트레이트 문서가 이제는 언제 구현해야 하는지 아주 명확하게 설명되어 있음

    • Rust를 아직 배우는 중인데, unwrap_or_else()라는 이름이 마치 “컴퓨터에게 협박하듯 명령하는” 느낌이라 재밌게 들림
  • 이런 방어적 프로그래밍 패턴이 대규모 AI 코드 생성 품질 향상에도 도움이 될 거라 생각함
    Clippy나 Rust 컴파일러가 제공하는 구체적 피드백이 AI 에이전트가 실수를 줄이고 방향을 잡는 데 큰 역할을 할 수 있음