我试图理解如何将HashMap中的值类型从&'t str更改为Value<'t>(&'t str),从而对下面传递给getKey类型提出更严格的要求.

#![allow(dead_code, unused)]
use std::collections::HashMap;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct Key<'t>(&'t str);

#[derive(Debug, Clone, Copy)]
struct Value<'t>(&'t str);

#[derive(Debug)]
struct Map1<'t>(HashMap<Key<'t>, &'t str>);

#[derive(Debug)]
struct Map2<'t>(HashMap<Key<'t>, Value<'t>>);

impl<'t> Map1<'t> {
    fn get<'map>(&'map self, key: &Key<'_>) -> Option<&'map str> {
        self.0.get(key).map(|x| *x)
    }
}

impl<'t> Map2<'t> {
    fn get<'map>(&'map self, key: &Key<'_>) -> Option<&'map Value<'t>> {
        // Doesn't work, says:    -------- help: add explicit lifetime `'map` to the type of `key`: `&Key<'map>`
        self.0.get(key)
    }
}

在值类型为&'t strMap1中,可以传入具有任意生存期的Key,而在值类型为Value<'t>(&'t str左右的新类型包装器)的Map2中,这就不再合适了,我应该传递一个其内部生存期与映射本身一样长的键.

你能帮我了解一下为什么会这样吗?

我能做些什么来使新型的包装Value(&str)&str一样工作吗?

推荐答案

这两个get实现并不等同:

        self.0.get(key).map(|x| *x)
        // vs
        self.0.get(key)

map实际上是在做copy().如果没有该副本,Map1::map方法的类型是什么?

impl<'t> Map1<'t> {
    fn get<'map>(&'map self, key: &Key<'_>) -> Option<&'map &'t str> {
        self.0.get(key)
    }
}

...这会给你带来同样的错误.

因此,您真正需要的是复制这Value个,例如:

impl<'t> Map2<'t> {
    fn get<'map>(&'map self, key: &Key<'_>) -> Option<Value<'t>> {
        self.0.get(key).copied()
    }
}

如果您不想这样做,那么与Map1相比,您的will自然需要更改生存期声明.

Rust相关问答推荐

给定使用newype习语定义的类型上的铁 rust Vec,有没有方法获得底层原始类型的一部分?

如何在原始字符串中转义";#和#";

为什么这是&q;,而让&q;循环是无限循环?

如何使用RefCell::JOYMOMTborrow 对 struct 不同字段的可变引用

变量需要parse()中的显式类型

在Rust中克隆源自INTO_ITER()的迭代器的成本?

习语选项<;T>;到选项<;U>;当T->;U用From定义

为什么将易错函数的泛型结果作为泛型参数传递 infer ()?不应该是暧昧的吗?

如何在 Rust 中将函数项变成函数指针

为什么这个闭包没有实现Fn?

从 Rust 中的 if/else 中的引用创建 MappedRwLockWriteGuard

borrow 匹配手臂内部的可变

了解 Rust 闭包:为什么它们持续持有可变引用?

如何将 Rust 中的树状 struct 展平为 Vec<&mut ...>?

在 Rust 中,为什么整数溢出有时会导致编译错误或运行时错误?

Rust 中函数的类型同义词

使用 HashMap 条目时如何避免字符串键的短暂克隆?

Cargo:如何将整个目录或文件包含在功能标志中?

Abortable:悬而未决的期货?

如何从 Rust 应用程序连接到 Docker 容器中的 SurrealDB?