T包装借来的数据时如何实现Borrow<T>?
How to implement Borrow<T> when T wraps borrowed data?
给出以下来自 的定义:
#[derive(Serialize)]
struct SerializeThing<'a> {
small_header: (u64, u64, u64),
big_body: &'a str,
}
#[derive(Deserialize)]
struct DeserializeThing {
small_header: (u64, u64, u64),
big_body: String,
}
我如何实现 Borrow
特征以便将拥有的数据自然地存储在(例如)HashMap 中并通过它们或它们借来的对应物查询它们?最接近的可能如下:
impl DeserializeThing {
fn as_serialize(&self) -> SerializeThing<'_> {
let DeserializeThing { small_header, big_body } = self;
let small_header = *small_header;
let big_body = big_body.as_str();
SerializeThing { small_header, big_body }
}
}
这还不够。
你不能。
Borrow::borrow
必须 return 一个引用,并且您无法从对 DeserializeThing
的引用中获取对 SerializeThing
的引用,因为这些类型是根本不兼容 ABI。
如果性能很重要并且您不能为 DeserializeThing
instances/allocation 字符串的构造付费,那么您可以使用 hashbrown::HashMap
而不是 std::collections::HashMap
。
hashbrown
是标准库用于其自身 HashMap
实现的库,但它有一些更有用的方法。
现在对您有用的一个是 raw entry API (and mutable raw entry)。
特别是,它允许您从其哈希和匹配函数中获取映射条目:
pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a > V)> where
F: FnMut(&K) -> bool
Access an entry by hash.
由于您可以为 DeserializeThing
和 SerializeThing
实现 Hash
以获得相同值的相同哈希值,因此 API 在你的情况。
给出以下来自
#[derive(Serialize)]
struct SerializeThing<'a> {
small_header: (u64, u64, u64),
big_body: &'a str,
}
#[derive(Deserialize)]
struct DeserializeThing {
small_header: (u64, u64, u64),
big_body: String,
}
我如何实现 Borrow
特征以便将拥有的数据自然地存储在(例如)HashMap 中并通过它们或它们借来的对应物查询它们?最接近的可能如下:
impl DeserializeThing {
fn as_serialize(&self) -> SerializeThing<'_> {
let DeserializeThing { small_header, big_body } = self;
let small_header = *small_header;
let big_body = big_body.as_str();
SerializeThing { small_header, big_body }
}
}
这还不够。
你不能。
Borrow::borrow
必须 return 一个引用,并且您无法从对 DeserializeThing
的引用中获取对 SerializeThing
的引用,因为这些类型是根本不兼容 ABI。
如果性能很重要并且您不能为 DeserializeThing
instances/allocation 字符串的构造付费,那么您可以使用 hashbrown::HashMap
而不是 std::collections::HashMap
。
hashbrown
是标准库用于其自身 HashMap
实现的库,但它有一些更有用的方法。
现在对您有用的一个是 raw entry API (and mutable raw entry)。
特别是,它允许您从其哈希和匹配函数中获取映射条目:
pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a > V)> where F: FnMut(&K) -> bool
Access an entry by hash.
由于您可以为 DeserializeThing
和 SerializeThing
实现 Hash
以获得相同值的相同哈希值,因此 API 在你的情况。