当前位置:  开发笔记 > 编程语言 > 正文

如何为枚举实现Borrow,ToOwned或Deref?

如何解决《如何为枚举实现Borrow,ToOwned或Deref?》经验,为你挑选了2个好方法。

我有一个看起来像这样的类型:

enum Name<'a> {
    Single(&'a str),
    Double(&'a str, &'a str),
}

另一个非常相似的类型看起来像这样:

enum OwnedName {
    Single(String),
    Double(String, String),
}

我已经有了一个将Name转换为OwnedName的方法.但是,我无法找到一种方法来实现像这样的类型Deref或者Borrow将OwnedName转换回Name.这意味着我必须两次编写相同的方法,这很烦人.我想要一些模仿方式PathBuf/ PathString/ str工作的东西.我尝试过这样的事情:

impl ops::Deref for OwnedName {
    type Target = Name;

    fn deref(&self) -> &Name {
        match *self {
            OwnedName::Single(ref s) => Name::Single(&**s),
            OwnedName::Double(ref s1, ref s2) => Name::Double(&**s1, &**s2),
        }
    }
}

这个错误随之wrong number of lifetime parameters: expected 1, found 0而来type Target = Name,这是完全可以理解的,因为它需要一生.但我不能提供一个.那么,有没有办法为我用Deref,或Borrow,或ToOwned用这种方式?



1> DK...:

没有办法做到这一点.

请注意,Deref::deref它的签名表示它需要指向a的指针,其Name生命周期与deref'ed相同.这样的值不存在.你也不能返回指向你在deref函数中创建的东西的指针,因为它不可能比它自己的堆栈帧寿命更长.

根本问题在于它Name基本上是一种不同类型的指针(就像*const T&T),但是Deref其他类似的特性允许你返回借来的指针.目前,这只是没有办法解决这个问题.

但是,如果你不使用Deref和其他类似的特性,你可以这样做.一种可能性是impl<'a> From<&'a OwnedName> for Name<'a>.


实际上,它*有可能从`Deref :: deref`返回函数内部创建的值:该值必须是胖指针.这就是`PathBuf`上的`Deref`实现如何工作 - 它返回`&Path`,这是一个指向未经过大小写的`Path`结构的胖指针.当然,这仅限于未指定类型的指针,不幸的是,不可能为`OwnedName`类型编写一个unsized枚举等效项,因此这种方法在这种情况下不起作用.

2> Paolo Falabe..:

我同意@DK.只要补充一点,如果您的想法是互换使用它们,您可能根本不需要OwnedName.您可以定义Name以同时接受&strString:

enum Name where T:Borrow {
    Single(T),
    Double(T, T),
}

// these both work now
let _a1 = Name::Single("hello");
let _a2 = Name::Double(String::from("hello"), String::from("world"));

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有