Trait Drop은 변수의 범위를 벗어날 때 자원을 정리하는 사용자 정의 로직을 정의할 수 있게 해줍니다. 주로 파일, 네트워크, 외부 및 안전하지 않은 자원을 해제하는 데 사용됩니다. Drop은 컴파일러에 의해 자동으로 호출됩니다.
예:
struct FileWrapper { fd: i32, } impl Drop for FileWrapper { fn drop(&mut self) { println!("Closing fd: {}", self.fd); unsafe { libc::close(self.fd); } } } fn main() { let file = FileWrapper { fd: 42 }; } // drop이 자동으로 호출됨
특징:
file.drop()을 통해 값의 drop을 명시적으로 호출할 수는 없지만, std::mem::drop(file)을 통해 호출할 수 있습니다.panic!)을 발생시키지 않아야 합니다. 이는 "double panic"과 프로세스 종료를 초래할 수 있습니다.질문: 구조체의 drop() 도중 자원의 소유권을 프로그램의 다른 부분으로 전달하려고 하면 어떻게 됩니까? 예를 들어, drop에서 반환하려고 하면?
답변: drop 중에 구조체의 필드 값을 다른 곳으로 "구조"하거나 전달할 수 없습니다. 값이나 소유권을 반환하려고 시도하면 컴파일 오류가 발생하거나 메모리 안전성이 침해됩니다(unsafe를 사용하는 경우). 오류 예:
impl Drop for MyStruct { fn drop(&mut self) -> T { // 오류: Drop::drop은 값을 반환할 수 없습니다! ... } }
이야기
파일 프로세서에서 원시 파일 디스크립터를 감싸는 구조체의 Drop을 구현하는 것을 잊었습니다. 수백 번의 작업 후 "파일 디스크립터 한도 초과" 오류가 발생했습니다. 자원이 해제되지 않았습니다.
이야기
네트워크 라이브러리에서 TCP 연결을 감싸는 Drop을 구현했지만 drop 시 소켓을 닫는 동안 패닉이 발생했습니다. 이는 double-panic으로 인해 스레드가 비정상 종료되는 원인이 되었습니다(유일한 방법은 Drop 내에서 패닉을 피하는 것입니다!).
이야기
플러그인 시스템에서 Drop을 통해 정리를 시도하면서 drop 중에 새로운 자원을 생성했습니다(예: 파일에 로깅). 이로 인해 관련 구조체에 대한 drop의 재귀 호출로 인해 "already borrowed: BorrowMutError"가 발생하고 자원이 누수되었습니다.