如何在已实现特征的现有类型枚举的范围内实现特征? [英] How can I implement a trait in scope for an enum of existing types for which the trait is implemented?

查看:48
本文介绍了如何在已实现特征的现有类型枚举的范围内实现特征?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在已实现特征的现有类型枚举的范围内实现特征?

我有这个:

extern crate pnet;使用 pnet::packet::ipv4::Ipv4Packet;使用 pnet::packet::ipv6::Ipv6Packet;枚举以太网类型{IPv4,ARP,VLAN,IPv6,未知(u16),}枚举 IPPacket<'a>{IPv4(Ipv4Packet<'a>),IPv6(Ipv6Packet<'a>),}fn ip_decode(pkt: &[u8]) ->IP包{让版本 = (pkt[0] & 0xf0) >>4;如果版本 == 4 {IPPacket::IPv4(Ipv4Packet::new(&pkt).unwrap())} 别的 {IPPacket::IPv6(Ipv6Packet::new(&pkt).unwrap())}}fn 主(){//在这里解析以太网数据包...//...让 ip_packet = ip_decode(b"deadbeef");println!("{:?}", ip_packet.payload());}

编译器抱怨我没有实现Packet trait 用于我的枚举:

error[E0599]: 在当前范围内没有找到类型为 `IPPacket<'_>` 的名为 `payload` 的方法-->src/main.rs:32:32|14 |枚举 IPPacket<'a>{|----------------- 没有为此找到方法`payload`...32 |println!("{:?}", ip_packet.payload());|^^^^^^^^|= help: 来自traits的项目只有在trait被实现并且在范围内时才能使用= 注意:以下 trait 定义了一个项目 `payload`,也许你需要实现它:候选 #1:`pnet::packet::Packet`

我认为 Packet trait 会通过 Ipv4Packet<'a>Ipv6Packet<'a>?

解决方案

如何在现有类型的枚举范围内实现特征

为枚举实现 trait 的方式与为结构体实现 trait 的方式相同:

trait 噪声 {fn 噪声(&self);}枚举 Foo {酒吧,巴兹,}Foo { 的 impl 噪声fn噪声(&self){匹配自我{Foo::Bar =>println!("bar bar bar"),Foo::Baz =>println!("baz baz baz"),}}}

<块引用>

已实现特征的现有类型的枚举

<块引用>

我认为 Packet trait 会被派生

事实并非如此.这样做会阻止人们在需要时为特征实现他们自己的代码.它也不会在所有情况下都有效,例如当一个变体没有实现它时.

trait 噪声 {fn 噪声(&self);}结构栏;Bar { 的 impl 噪声fn噪声(&self){println!("bar bar bar");}}结构巴兹;Baz 的 impl 噪声 {fn噪声(&self){println!("baz baz baz");}}枚举 Foo {酒吧(酒吧),巴兹(巴兹),}Foo { 的 impl 噪声fn噪声(&self){匹配自我{Foo::Bar(bar) =>酒吧噪音(),Foo::Baz(baz) =>baz.noise(),}}}

从概念上讲,可以扩展该语言以支持某些注释来执行此操作,但我从未听说有人建议这样做.您可以考虑创建一个 RFC 来添加它.

也许你可以回到教你这个的源头,从根本上纠正问题,防止其他人以同样的方式混淆.

另见:

How can I implement a trait in scope for an enum of existing types for which the trait is implemented?

I have this:

extern crate pnet;

use pnet::packet::ipv4::Ipv4Packet;
use pnet::packet::ipv6::Ipv6Packet;

enum EthernetType {
    IPv4,
    ARP,
    VLAN,
    IPv6,
    Unknown(u16),
}

enum IPPacket<'a> {
    IPv4(Ipv4Packet<'a>),
    IPv6(Ipv6Packet<'a>),
}

fn ip_decode(pkt: &[u8]) -> IPPacket {
    let version = (pkt[0] & 0xf0) >> 4;
    if version == 4 {
        IPPacket::IPv4(Ipv4Packet::new(&pkt).unwrap())
    } else {
        IPPacket::IPv6(Ipv6Packet::new(&pkt).unwrap())
    }
}

fn main() {
    // Parse ethernet packet here...
    // ...
    let ip_packet = ip_decode(b"deadbeef");
    println!("{:?}", ip_packet.payload());
}

The compiler complains that I have not implemented the Packet trait for my enum:

error[E0599]: no method named `payload` found for type `IPPacket<'_>` in the current scope
  --> src/main.rs:32:32
   |
14 | enum IPPacket<'a> {
   | ----------------- method `payload` not found for this
...
32 |     println!("{:?}", ip_packet.payload());
   |                                ^^^^^^^
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `payload`, perhaps you need to implement it:
           candidate #1: `pnet::packet::Packet`

I thought that the Packet trait would be derived through Ipv4Packet<'a> and Ipv6Packet<'a>?

解决方案

How can I implement a trait in scope for an enum of existing types

You implement a trait for an enum the same way you implement a trait for a struct:

trait Noise {
    fn noise(&self);
}

enum Foo {
    Bar,
    Baz,
}

impl Noise for Foo {
    fn noise(&self) {
        match self {
            Foo::Bar => println!("bar bar bar"),
            Foo::Baz => println!("baz baz baz"),
        }
    }
}

an enum of existing types for which the trait is implemented

I thought that the Packet trait would be derived

It is not. Doing so would prevent people from implementing their own code for the trait if they needed. It also wouldn't work in all cases, such as when one variant didn't implement it.

trait Noise {
    fn noise(&self);
}

struct Bar;

impl Noise for Bar {
    fn noise(&self) {
        println!("bar bar bar");
    }
}

struct Baz;

impl Noise for Baz {
    fn noise(&self) {
        println!("baz baz baz");
    }
}

enum Foo {
    Bar(Bar),
    Baz(Baz),
}

impl Noise for Foo {
    fn noise(&self) {
        match self {
            Foo::Bar(bar) => bar.noise(),
            Foo::Baz(baz) => baz.noise(),
        }
    }
}

It's conceptually possible that the language could be extended to support some annotation to do this, but I've never heard of anyone suggesting it. You could consider creating an RFC to add it.

Perhaps you can go back to the source that taught you this and correct the problem at the root to prevent other peopl from being confused in the same manner.

See also:

这篇关于如何在已实现特征的现有类型枚举的范围内实现特征?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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