【问题标题】:Is it possible to implement methods on type aliases?是否可以在类型别名上实现方法?
【发布时间】:2016-06-04 18:40:50
【问题描述】:

考虑以下实现:

pub struct BST {
    root: Link,
}

type Link = Option<Box<Node>>;

struct Node {
    left: Link,
    elem: i32,
    right: Link,
}

impl Link { /* misc */ }

impl BST { /* misc */ }

我不断收到错误:

不能为定义类型的 crate 之外的类型定义固有的impl;定义并实现一个 trait 或新类型

我能够找到其他人had this same issue back in February,但当时似乎没有解决方案。

我有什么修复方法或其他方法可以在 Rust 中实现我的 Link typedef 吗?

【问题讨论】:

    标签: rust


    【解决方案1】:

    有什么解决办法

    不是真的。 类型别名 (type Foo = Bar) 不会 创建新类型。它所做的只是创建一个引用现有类型的不同名称。

    在 Rust 中,不允许为来自另一个 crate 的类型实现固有方法。

    我的另一种实现方式

    正常的解决方案是创建一个全新的类型。其实就是goes by the name newtype

    struct Link(Option<Box<Node>>);
    
    impl Link {
        // methods all up in here
    }
    

    这在运行时没有缺点 - 两个版本将占用完全相同的空间量。此外,您不会意外暴露任何您不打算使用的方法。例如,您真的希望您的代码的客户端能够调用Option::take吗?

    另一种解决方案是创建您自己的trait,然后为您的类型实现它。从调用者的角度来看,它看起来基本相同:

    type Link = Option<Box<Node>>;
    
    trait LinkMethods {
        fn cool_method(&self);
    }
    
    impl LinkMethods for Link {
        fn cool_method(&self) {
            // ...
        }
    }
    

    这里的烦恼是特征LinkMethods 必须在范围内才能调用这些方法。你也不能为你不拥有的类型实现你不拥有的特征。

    另见:

    【讨论】:

    • Re: "methods all up here": 有没有一种快速的方法来“代理”我想要保留的所有方法,而不是我正在包装的类型?例如使用struct MyList(Vec&lt;MyData&gt;),我想获得所有可枚举的东西,而不必重新编写所有方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多