TypeId 컨텐츠 체크 아웃
std::cmp::Eq
,std::cmp::Ord
,std::hash::Hash
등을 실시했기 때문에 그렇게 사전의 열쇠로 삼는 것은 가능하지만 이 보도에서 우리는 그 내용(강제적이지만 안전히)을 꺼내는 것을 고려했다.주의점은 이 글의 내용이
TypeId
의 내부 실시에 의존하면 장래TypeId
의 내부 구조가 변경될 때 행동이 이상해질 수 있다는 것이다.내부 상태가 필요한 이유
표준고
TypeId
를 보면 이런 구조입니다.pub struct TypeId {
t: u64,
}
여기t
에 pub
등이 있다면[1] 말이 빠르지만 아쉽게도 이것t
이 숨겨져 있다.숨겨진 이상 Rust 개발자들은 내부 상태를 직접 이용하는 것을 고려하지 않고 이런 기사를 썼는데 나도 기본적으로 직접 사용해서는 안 된다.
그래도 내부 상태를 원하는 경우가 있어요.
삼각목은 연상 배열로 사용할 수 있는 데이터 구조이지만 반드시 열쇠를 바이트열로 사용해야 한다.
예를 들어qp_trie 이런 기중기는 삼각목의 일종인 QP-trie를 실현했지만 열쇠를 요구하는 것은
Borrow<[u8]>
이다.따라서
TypeId
상태를 유지하면 키로 처리할 수 없지만 내부 상태를 꺼내면 키로 처리할 수 있다.FFI와 통신에 사용되는 경우에도 예컨대
(Vec<TypeId>, std::collections::HashMap<TypeId, usize>)
와 같은 구조를 준비하지 않고 출입구에서 이런 손을 물어뜯는 것은 아니다.그러나 단순히 유일한 ID로서 단시간(저장한 뒤 다시 읽는 등 하지 않음) 활용이라면 그렇게 내부 상태를 사용해도 문제가 없을 것이고, 전환 비용도 필요 없을 것이다.
'시목 대신 해시맵을 쓰면 된다','큰 비용이 아니기 때문에 씹는 전환이 좋다'는 판단도 나쁘지 않을 것이다.대부분의 경우 그만하면 충분하겠지.필자가 단지 연기의 명수일 뿐이라면, 그것은.
std:hash:Hasher 설치
실제로 무엇을 해야 하는지
TypeId
남용 실시Hash
.실시
Hasher
의 유형, Hash::hash()
라고 부르면 Hasher::write()
등을 통해 내부 상태로부터의 값을 받아들일 수 있다.#[derive(Default)]
struct TypeIdHasher(u64, u32);
impl Hasher for TypeIdHasher {
fn write(&mut self, bytes: &[u8]) {
for &b in bytes {
self.0 ^= (b as u64).rotate_left(self.1);
self.1 = (self.1 + 8) % 64;
}
}
fn write_u64(&mut self, i: u64) {
self.0 ^= i.rotate_left(self.1);
}
fn finish(&self) -> u64 {
self.0
}
}
fn type_id_inner(type_id: &TypeId) -> u64 {
let mut hasher = TypeIdHasher::default();
type_id.hash(&mut hasher);
hasher.finish()
}
이런 느낌이에요.Hasher
는 실현write
과finish
가 가능하지만 TypeId
의 내부 상태는u64
이기 때문에 write_u64
호칭이 기대된다.또 이 시행방식에서 예컨대
TypeId
의 내부상태가 u128
일 경우TypeIdHasher
의 내부상태가 부족해 충돌이 발생하는데, write_u64
가 아닌 write
일 때 대endian의 환경에서는 기존 내부상태와 다른 값[2]을 받을 수 있다.같은 방법으로 내부는 비공개이지만 해시가 설치된 유형에서 내부 상태를 꺼낼 수 있다.나는 해야 한다고 말하지 않았다.
추가:안전하지 않은 방법
fn type_id_inner(type_id: &TypeId) -> u64 {
let ptr = type_id as *const TypeId as *const u64;
unsafe { *ptr }
}
더 이상은 안 돼.각주
pub
가 있으면 내부 상태가 바뀌어 추가되지 않습니다.예를 들어 Borrow<u64>
↩︎도 가능합니다.이 점에 관해서는 최소한 정보량이 같고 단순한 유일한 ID로만 이용된다면 문제가 될 수 없다↩︎
Reference
이 문제에 관하여(TypeId 컨텐츠 체크 아웃), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/kazatsuyu/articles/be3715cd3d1279dc0c11텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)