简体   繁体   English

Rust 中的“impl const”是什么?

[英]What is "impl const" in Rust?

I see this a lot in Rust code.我在 Rust 代码中经常看到这一点。 Here are a few examples from the standard library:以下是标准库中的一些示例:

impl<T> const Default for Option<T> {...}

impl const From<char> for u64 {...}

What is impl const ?什么是impl const

If you run the code:如果你运行代码:

trait Example {}
impl const Example for u8 {}

You get an error message that points you in the right direction:您会收到一条错误消息,指出您正确的方向:

error[E0658]: const trait impls are experimental
 --> src/lib.rs:3:6
  |
3 | impl const Example for u8 {}
  |      ^^^^^
  |
  = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
  = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable

Issue 67792 is the tracking issue for RFC 2632 — Calling methods on generic parameters of const fns .问题 67792RFC 2632 的跟踪问题 — 在 const fns 的通用参数上调用方法

This is an unstable syntax that allows defining traits that can be used in a const context.这是一种不稳定的语法,允许定义可在const上下文中使用的特征。 It's paired with the equally unstable ~const syntax that can be used in trait bounds:它与同样不稳定~const语法配对,可用于 trait bound:

// 1.59.0-nightly (2021-12-20 23f69235ad2eb9b44ac1)
#![feature(const_fn_trait_bound)]
#![feature(const_trait_impl)]

trait Example {
    fn usage(&self) -> Self;
}

impl const Example for u8 {
    fn usage(&self) -> Self {
        42
    }
}

const fn demo<T: ~const Example>(v: &T) -> T {
    v.usage()
}

const VALUE: u8 = demo(&1);

fn main() {
    dbg!(VALUE);
}

I accepted Shepmaster's answer, but as this question has been gaining popularity, I thought it might also be useful to add some more insight into those const rules.我接受了 Shepmaster 的回答,但随着这个问题越来越受欢迎,我认为对这些const规则添加一些更多的了解也可能会有用。 I'll use the same example provided by Shepmaster.我将使用 Shepmaster 提供的相同示例。 A few things have changed since he posted it, so I've updated the example with comments.自从他发布后,一些事情发生了变化,所以我用评论更新了这个例子。

// 1.68.0-nightly (2022-12-11 bdb07a8ec8e77aa10fb8)

//#![feature(const_fn_trait_bound)]   <-- Not needed since Rust 1.61
#![feature(const_trait_impl)]  // const trait impls are (still) experimental/unstable

#[const_trait]  // This is needed now
trait Example {
    fn usage(&self) -> Self;
}

impl const Example for u8 {
    fn usage(&self) -> Self {
        42
    }
}

const fn demo<T: ~const Example>(v: &T) -> T {
    v.usage()
}

const VALUE: u8 = demo(&1);

fn main() {
    dbg!(VALUE);
}

Let's say we started with no other const s apart from const VALUE .假设我们开始时除了const VALUE之外没有其他const If fn demo were not const fn demo , we would have gotten this error:如果fn demo不是const fn demo ,我们就会得到这个错误:

error[E0015]: cannot call non-const fn `demo::<u8>` in constants

So far, that has nothing to do with traits per se.到目前为止,这与特质本身无关。 But if we just changed fn demo to const fn demo , the compiler would complain with:但是如果我们只是将fn demo更改为const fn demo ,编译器会报错:

error[E0277]: the trait bound `T: ~const Example` is not satisfied
    note: the trait `Example` is implemented for `T`, but that implementation is not `const`

and

error[E0015]: cannot call non-const fn `<T as Example>::usage` in constant functions
    note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

Just adding a trait bound ~const to Example wouldn't do:仅仅向Example添加一个 trait bound ~const是不行的:

error: ~const can only be applied to `#[const_trait]` traits

We need to add #[const_trait] to trait Example and change impl Example to impl const Example .我们需要将#[const_trait]添加到trait Example并将impl Example更改为impl const Example

#[const_trait] was added recently and is now required on Trait for impl const Trait . #[const_trait]最近添加,现在impl const TraitTrait上是必需的

Some more info by the compiler when #[const_trait] is missing:缺少#[const_trait]时编译器提供的更多信息:

error: const `impl` for trait `Example` which is not marked with `#[const_trait]`
  
   |
7  | trait Example {
   | - help: mark `Example` as const: `#[const_trait]`
...
11 | impl const Example for u8 {
   |            ^^^^^^^
   |
   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
   = note: adding a non-const method body in the future would be a breaking change

As explained here , the rational behind requiring #[const_trait] on trait Example when we have impl const Example is that that prevents adding a new default method to Example from becoming a breaking change (as it could be a non-const fn).正如这里所解释的,当我们有impl const Example时,在trait Example上要求#[const_trait]背后的合理性是,这可以防止向Example添加一个新的默认方法成为一个破坏性的变化(因为它可能是一个非常量 fn)。

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

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