【问题标题】:Why does Rust want Self to be Sized when implementing an associated const with an associated type?为什么在实现具有关联类型的关联 const 时,Rust 希望 Self 被调整大小?
【发布时间】:2018-06-29 06:20:10
【问题描述】:

考虑以下代码:

pub trait Trait {
  type Type;
  const CONST: Self::Type;
}

impl<T> Trait for T {
  type Type = u8;
  const CONST: u8 = 42;
}

我(不正确?)对 Rust 的理解是这段代码应该可以工作,并且所有 Sized 类型现在都应该实现 Trait 并具有关联的类型 (Type = u8) 和 const (CONST = 42)。未调整大小的类型不应实现此特征,因为 impl&lt;T&gt; 隐式假定 TSized

但是,当我尝试compile the code 时,我收到错误消息:

error[E0277]: the size for value values of type `T` cannot be known at compilation time
 --> src/main.rs:8:3
  |
8 |   const CONST: u8 = 42;
  |   ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `T`
  = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
  = help: consider adding a `where T: std::marker::Sized` bound
  = note: required because of the requirements on the impl of `Trait` for `T`

我的问题:

  • 为什么Rust 认为T 不是SizedExplicitly stating T: Sized doesn't help
  • 让我们假设T 不是Sized。为什么 Rust 会关心 T 的大小是否在这里?据我所知,没有什么取决于它(关联的类型和 const 与T 无关)。将代码更改为 T: ?Sized 有效,因此很明显 T 未调整大小实际上并没有问题。

【问题讨论】:

  • 这似乎是一个错误。有一个open issue
  • 您的意思是写impl&lt;T: Sized&gt; Trait for T? (这并不能解决问题,但更符合您的问题描述)
  • @kazemakase:谢谢!如果您将其发布为答案,我会接受。
  • @Cornstalks “这是一个错误”很难给出一个好的答案......但显然它是唯一的一个:(

标签: rust


【解决方案1】:

根据this GitHub issue,这似乎是一个已知的错误,至少从 Rust 1.23 开始就存在(我怀疑更长)。

目前尚不清楚导致问题的原因以及何时/是否会修复。只有一个相当模糊的假设:

我不熟悉编译器的内部结构,但我的假设是,依赖于类型参数的关联类型和常量在常量表达式求值器中没有正确求值。在这种情况下,它的关联类型不能很好地减少:const VAL: Self::T = 5; 强制 Rust 在编译时进行一些花哨的计算以进行类型检查,但此类计算的代码中有一个错误。

有几种方法可以解决此问题:

  1. 在 trait 中指定具体类型:

    pub trait Trait {
        // type Type;  // no longer used
        const CONST: u8;
    }
    
  2. Sized 中选择T

    impl<T: ?Sized> Trait for T {
        type Type = u8;
        const CONST: u8 = 42;
    }
    
  3. 使用函数而不是常量(感谢 @PeterHall):

    pub trait Trait {
      type Type;
      fn const_val() -> Self::Type;
    }
    
    impl<T> Trait for T {
      type Type = u8;
      fn const_val() -> Self::Type { 42 }
    }
    

【讨论】:

  • 作为一种解决方法,你不能只在 trait 中使用函数而不是 const 吗?它应该内联到同一件事。
  • @PeterHall 你当然是对的。感谢您指出这一疏忽。
猜你喜欢
  • 1970-01-01
  • 2020-03-31
  • 2020-05-13
  • 2022-11-03
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 2023-02-23
相关资源
最近更新 更多