【发布时间】:2015-07-31 19:42:13
【问题描述】:
我有点卡住了(除了复制我的记忆(参见playpen 中的 DupKeyEAB),我得到了这个特征:
pub trait KeyVal : Send + Sync + 'static {
type Key : Clone + Debug + 'static;
fn get_key(&self) -> Self::Key;
fn get_key_ref<'a>(&'a self) -> &'a Self::Key;
}
我的问题是我需要类似的东西(避免每次访问密钥时都使用克隆):
pub trait KeyVal : Send + Sync + 'static {
type Key : Clone + Debug + 'static;
type KeyRef<'_> : Debug;
fn get_key(&self) -> Self::Key;
fn get_key_ref<'a>(&'a self) -> Self::KeyRef<'a>;
}
或直接(以 KeyRef 作为特征)
fn get_key_ref<'a,K : KeyRef<'a>>(&'a self) -> K;
或
fn get_key_ref<'a>(&'a self) -> KeyRef<'a>;
所有这些符号显然都非常无效,但它说明我需要返回一个与实现我的特征的结构具有相同生命周期的引用,但同时该引用不能简单地是 &'a 而是一个枚举相同的寿命。
这样,当在简单结构上使用 get_key_ref 时,我的 KeyRef 只是 &'aKey,当在 枚举组合多个特征实现上使用 get_key_ref 时(请参阅EnumAB),我可以在引用上使用包装枚举到关键:像KeyABRef<'a>。
impl EnumAB {
fn get_key_ok<'a>(&'a self) -> KeyABRef<'a> {
match self {
&EnumAB::A(ref a) => KeyABRef::A(a.get_key_ref()),
&EnumAB::B(ref b) => KeyABRef::B(b.get_key_ref()),
}
}
}
但我不能在我的特质中包含这个功能。 我想知道是否有人为这种需求找到了解决方案(KeyVal 需要是“静态的”)?
我原来的测试代码是:
use std::fmt::Debug;
use std::thread;
pub trait KeyVal : Send + Sync + 'static {
type Key : Clone + Debug + 'static;
fn get_key(&self) -> Self::Key;
fn get_key_ref<'a>(&'a self) -> &'a Self::Key;
}
pub fn do_something_with_spawn<KV : KeyVal> (kv : KV) {
thread::spawn ( move || {
println!("{:?}", kv.get_key_ref());
});
}
#[derive(Debug)]
pub struct StructA (usize);
#[derive(Debug)]
pub struct StructB (String);
#[derive(Debug)]
pub enum EnumAB {
A(StructA),
B(StructB),
}
impl KeyVal for StructA {
type Key = usize;
// type KeyRef<'_> = &'_ usize;
fn get_key(&self) -> Self::Key {
self.0.clone()
}
fn get_key_ref<'a>(&'a self) -> &'a Self::Key {
&self.0
}
}
impl KeyVal for StructB {
type Key = String;
// type KeyRef<'_> = &'_ String;
fn get_key(&self) -> Self::Key {
self.0.clone()
}
fn get_key_ref<'a>(&'a self) -> &'a Self::Key {
&self.0
}
}
#[derive(Clone,Debug)]
pub enum KeyAB {
A(usize),
B(String),
}
#[derive(Clone,Debug)]
pub enum KeyABRef<'a> {
A(&'a usize),
B(&'a String),
}
impl KeyVal for EnumAB {
type Key = KeyAB;
// type KeyRef<'_> = KeyABRef<'_>
fn get_key(&self) -> Self::Key {
match self {
&EnumAB::A(ref a) => KeyAB::A(a.get_key()),
&EnumAB::B(ref b) => KeyAB::B(b.get_key()),
}
}
fn get_key_ref<'a>(&'a self) -> &'a Self::Key {
panic!("cannot");
}
}
impl EnumAB {
fn get_key_ok<'a>(&'a self) -> KeyABRef<'a> {
match self {
&EnumAB::A(ref a) => KeyABRef::A(a.get_key_ref()),
&EnumAB::B(ref b) => KeyABRef::B(b.get_key_ref()),
}
}
}
#[derive(Debug)]
pub struct DupKeyEAB (KeyAB, EnumAB);
impl KeyVal for DupKeyEAB {
type Key = KeyAB;
fn get_key(&self) -> Self::Key {
self.0.clone()
}
fn get_key_ref<'a>(&'a self) -> &'a Self::Key {
&self.0
}
}
fn main () {
let d2 = StructB("hello".to_string());
let d3 = EnumAB::A(StructA(3));
println!("{:?}",d2.get_key());
println!("{:?}",d3.get_key());
println!("{:?}",d2.get_key_ref());
println!("{:?}",d3.get_key_ok());
do_something_with_spawn(d3);
}
【问题讨论】:
-
您能否提供一个您要解决的问题的最小可编译示例?您现在的问题是关于对某些尚未描述的问题的尝试的无效解决方案。您很有可能可以在安全的 Rust 中解决您最初的问题。