简体   繁体   English

类型绑定中的特征“未实现”?

[英]Trait in type bound “not implemented”?

Consider the following code, which uses a trait to make the length of an array fixed in the type.考虑以下代码,它使用 trait 使数组的长度在类型中固定。

use std::marker::PhantomData;

pub trait MyLen {
    const LEN: usize;
}

pub struct Data<L: MyLen> {
    bytes: [u8; <L as MyLen>::LEN],
    _phantom: PhantomData<L>,
}

I could swear I saw similar code work a couple days ago, but now I'm seeing我可以发誓几天前我看到了类似的代码,但现在我看到了

   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `L: MyLen` is not satisfied
 --> src/lib.rs:8:17
  |
4 |     const LEN: usize;
  |     ----------------- required by `MyLen::LEN`
...
8 |     bytes: [u8; <L as MyLen>::LEN],
  |                 ^^^^^^^^^^^^^^^^^ the trait `MyLen` is not implemented for `L`
  |
help: consider further restricting this bound
  |
7 | pub struct Data<L: MyLen + MyLen> {
  |                          ^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`

This error message doesn't make sense to me, especially not the suggestion.此错误消息对我来说没有意义,尤其是建议。 Any ideas what I'm doing wrong?任何想法我做错了什么?

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=49c9a11106a46125eaa9612560966bac操场: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=49c9a11106a46125eaa9612560966bac

First of all, you'll need to use theconst_generics feature to be able to do that.首先,您需要使用const_generics功能才能做到这一点。 However, that's not entirely enough, as you'll also need to use the const_evaluatable_checked feature .然而,这还不够,因为您还需要使用const_evaluatable_checked功能

When you add the const_generics feature, then the issue becomes apparent with a more descriptive compiler error.当您添加const_generics功能时,问题会变得很明显,并且会出现更具描述性的编译器错误。

error: constant expression depends on a generic parameter
  --> src\main.rs:37:12
   |
37 |     bytes: [u8; <L as MyLen>::LEN],
   |            ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this may fail depending on what value the parameter takes

error: constant expression depends on a generic parameter
  --> src\main.rs:34:30
   |
34 |     [u8; <L as MyLen>::LEN]: Sized,
   |                              ^^^^^
   |
   = note: this may fail depending on what value the parameter takes

The missing part is where [u8; <L as MyLen>::LEN]:缺少的部分是where [u8; <L as MyLen>::LEN]: where [u8; <L as MyLen>::LEN]: (or where [u8; <L as MyLen>::LEN]: Sized ) which requires the const_evaluatable_checked feature. where [u8; <L as MyLen>::LEN]: (或where [u8; <L as MyLen>::LEN]: Sized )需要const_evaluatable_checked功能。 The where clause is needed, to ensure that LEN doesn't evaluate into something that overflows or otherwise invalidates that array.需要 where 子句,以确保LEN不会评估为溢出或以其他方式使该数组无效的内容。

You can read more about it on this HackMD post by the Rust Compiler Team.您可以在 Rust 编译器团队的这篇HackMD 帖子中了解更多信息。

#![feature(const_generics)]
#![feature(const_evaluatable_checked)]
#![allow(incomplete_features)]

use std::marker::PhantomData;

pub trait MyLen {
    const LEN: usize;
}

pub struct Data<L: MyLen>
where
    [u8; <L as MyLen>::LEN]: ,
    // or
    // [u8; <L as MyLen>::LEN]: Sized,
{
    bytes: [u8; <L as MyLen>::LEN],
    _phantom: PhantomData<L>,
}

Which of course requires a nightly compiler to build.这当然需要一个夜间编译器来构建。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM