是否可以在类型别名上实现方法? [英] Is it possible to implement methods on type aliases?

查看:54
本文介绍了是否可以在类型别名上实现方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下实现:

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;而是定义并实现一个特征或新类型

cannot define inherent impl for a type outside of the crate where the type is defined; define and implement a trait or new type instead

我发现其他人在二月份遇到了同样的问题,但当时似乎没有解决方案.

I was able to find others had this same issue back in February, but there was seemingly no solution at the time.

是否有任何修复或其他方法可以让我在 Rust 中实现我的 Link typedef?

Is there any fix or another way for me to implement my Link typedef in Rust?

推荐答案

有什么解决办法

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

Not really. A type alias (type Foo = Bar) does not create a new type. All it does is create a different name that refers to the existing type.

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

In Rust, you are not allowed to implement inherent methods for a type that comes from another crate.

另一种实现方式

通常的解决方案是创建一个全新的类型.事实上,它 名称为newtype

The normal solution is to create a brand new type. In fact, it goes by the name newtype!

struct Link(Option<Box<Node>>);

impl Link {
    // methods all up in here
}

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

There's no runtime disadvantage to this - both versions will take the exact same amount of space. Additionally, you won't accidentally expose any methods you didn't mean to. For example, do you really want clients of your code to be able to call Option::take?

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

Another solution is to create your own trait, and then implement it for your type. From the callers point of view, it looks basically the same:

type Link = Option<Box<Node>>;

trait LinkMethods {
    fn cool_method(&self);
}

impl LinkMethods for Link {
    fn cool_method(&self) {
        // ...
    }
}

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

The annoyance here is that the trait LinkMethods has to be in scope to call these methods. You also cannot implement a trait you don't own for a type you don't own.

另见:

这篇关于是否可以在类型别名上实现方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆