【问题标题】:How to implement Borrow<T> when T wraps borrowed data?T包装借来的数据时如何实现Borrow<T>?
【发布时间】:2021-01-20 13:34:04
【问题描述】:

鉴于How to borrow a field for serialization but create it during deserialization? 的以下定义:

#[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 特征,以便将拥有的数据自然地存储在(例如)HashMaps 中,并通过它们或借用的对应物查询它们?可能出现的最接近的情况如下:

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 }
    }
}

这还不够。

【问题讨论】:

    标签: rust traits borrow-checker


    【解决方案1】:

    你不能。

    Borrow::borrow 必须返回一个引用,并且您无法从对 DeserializeThing 的引用中获得对 SerializeThing 的引用,因为这些类型根本不兼容 ABI。


    如果性能很重要,并且您无法支付DeserializeThing 实例/字符串分配的费用,那么您可以使用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
    

    通过哈希访问条目。

    由于您可以为 DeserializeThingSerializeThing 实现 Hash 以获得相同值的相同哈希值,因此此 API 在您的情况下使用起来很简单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 2020-07-19
      • 2011-10-09
      相关资源
      最近更新 更多