问题
I've got a trait which represents an entity that can be sent through UDP sockets:
pub trait ToNetEnt {
const NET_SIZE: usize;
fn from_net(data: &[u8]) -> Self;
fn to_net(&self) -> &[u8];
}
Though there is an associated constant NET_SIZE
, I couldn't use it in methods:
pub fn req<T: ToNetEnt>(&self) -> T {
let buf: [u8; T::NET_SIZE];
}
because it causes this error:
error[E0599]: no associated item named `NET_SIZE` found for type `T` in the current scope
--> src/main.rs:10:23
|
10 | let buf: [u8; T::NET_SIZE];
| ^^^^^^^^^^^ associated item not found in `T`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `NET_SIZE`, perhaps you need to implement it:
candidate #1: `ToNetEnt`
Can I use an associated constant in this context?
回答1:
At time of writing this is not possible. But let's first fix your code:
pub fn req<T: ToNetEnt>(&self) -> T {
let buf: [u8; <T as ToNetEnt>::NET_SIZE];
...
}
playground
This should be the right syntax, but does not compile at the moment:
error[E0277]: the trait bound `T: ToNetEnt` is not satisfied
--> src/main.rs:6:19
|
6 | let buf: [u8; <T as ToNetEnt>::NET_SIZE];
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ToNetEnt` is not implemented for `T`
|
= help: consider adding a `where T: ToNetEnt` bound
which is simply a wrong error message to the problem. See this comment on GitHub:
[U]sing an associated const as an array size does not appear to work:
pub trait Can { const SIZE: usize; } fn f<T: Can>(t: T) { // error[E0277]: the trait bound `T: Can` is not satisfied let x = [0u8; <T as Can>::SIZE]; }
There error message is clearly wrong, so this is either a bug in
rustc
or unimplemented functionality resulting in a bogus error message.
You can workaround this when defining the const NET_SIZE
in your struct directly.
You can read more about this at the GitHub issue for this specific bug: Array lengths don't support generic type parameters (#43408).
回答2:
To access an associated constant, you need to explicitly say which trait it is coming from, using this slightly cumbersome syntax: <T as ToNetEnt>::NET_SIZE
.
来源:https://stackoverflow.com/questions/51131229/how-to-use-associated-constants-to-define-the-length-of-an-array