질문 배경
HashSet과 HashMap은 std::collections에서 제공하는 표준 구조체로, 해시를 통한 빠른 검색을 구현합니다. 이들은 Rust의 초기 버전부터 내장되어 있지만, 사용 시 내부 세부 사항은 종종 경험이 많은 개발자에게도 어려움을 초래할 수 있는 소유권 시스템으로 인해 복잡합니다.
문제점
값이 Copy가 아닐 때 특히 요소를 삽입하고 추출할 때 혼란이 발생하며, 컬렉션을 변경할 때(가변 참조) 또한 키로서 참조를 사용할 때 문제가 발생합니다. 사용자 정의 유형에 대한 올바른 Eq/Hash 구현에도 문제가 있습니다.
해결책
코드 예시:
use std::collections::HashMap; fn main() { let mut map = HashMap::new(); map.insert("key", 42); if let Some(value) = map.get("key") { println!("Found value: {}", value); } }
주요 특징:
HashMap의 동일한 요소에 대해 여러 가변 참조를 가져올 수 있습니까?
아니요, 대출 검사기가 이를 허용하지 않아 소유권 위반을 방지합니다.
문자열 리터럴 "abc"를 HashMap<String, V>의 키로 직접 사용할 수 있습니까?
아니요, 정확히 String이 예상되며, "abc"는 &'static str입니다. 변환이 필요합니다: insert("abc".to_string(), val).
HashMap에서 값을 별도의 변수에 저장하고 계속 HashMap을 사용할 수 있습니까?
네, get을 통해 값에 대한 참조를 가져올 수 있지만, remove(혹은 이동에 의해 추출)하면 HashMap이 수정되어 이전의 모든 참조가 유효하지 않게 됩니다.
키와 값을 동시에 대출하려다가 컬렉션을 변경하려는 시도:
let mut map = HashMap::new(); map.insert("abc".to_string(), 10); let val = map.get("abc"); map.insert("def".to_string(), 20); // 대출 검사기 오류
장점:
단점:
값 추출, 복사 또는 클론만 사용:
let mut map = HashMap::new(); map.insert("abc".to_string(), 10); if let Some(val) = map.get("abc") { let val = *val; // 복사합니다. map.insert("def".to_string(), 20); // 모든 것이 작동합니다. }
장점:
단점: