问题
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>
?
回答1:
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:
- Can traits be used on enum types?
来源:https://stackoverflow.com/questions/51661392/how-can-i-implement-a-trait-in-scope-for-an-enum-of-existing-types-for-which-the