Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在实现具有关联类型的关联常量时,Rust为什么希望调整Self的大小?_Rust - Fatal编程技术网

在实现具有关联类型的关联常量时,Rust为什么希望调整Self的大小?

在实现具有关联类型的关联常量时,Rust为什么希望调整Self的大小?,rust,Rust,考虑以下代码: pub trait Trait { type Type; const CONST: Self::Type; } impl<T> Trait for T { type Type = u8; const CONST: u8 = 42; } 我的问题是: 为什么Rust认为T的大小不在这里 让我们假设T没有大小。为什么Rust会在意T是否在此处调整尺寸?据我所知,没有什么依赖于它(关联的类型和常量与t无关)。将代码更改为T:?Sized有效,因此显然T

考虑以下代码:

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

impl<T> Trait for T {
  type Type = u8;
  const CONST: u8 = 42;
}
我的问题是:

  • 为什么Rust认为
    T
    的大小不在这里
  • 让我们假设
    T
    没有
    大小
    。为什么Rust会在意
    T
    是否在此处调整尺寸?据我所知,没有什么依赖于它(关联的类型和常量与
    t
    无关)。将代码更改为
    T:?Sized
    有效,因此显然
    T
    未调整大小实际上没有问题
根据,这似乎是一个已知的缺陷,至少从Rust 1.23(我怀疑更长)开始就存在了

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

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

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

  • 在特征中指定具体类型:

    pub trait Trait {
        // type Type;  // no longer used
        const CONST: u8;
    }
    
  • 选择
    T
    超出
    大小

    impl<T: ?Sized> Trait for T {
        type Type = u8;
        const CONST: u8 = 42;
    }
    
    T的impl特征{
    类型=u8;
    常数:u8=42;
    }
    
  • 使用函数而不是常量(归功于@PeterHall):

    pub特征{
    类型;
    fn const_val()->Self::Type;
    }
    T的内隐性状{
    类型=u8;
    fn const_val()->Self::Type{42}
    }
    

  • 这似乎是一个错误。它有一个对应的属性。你是想为T
    编写
    impl Trait吗?(这并不能解决问题,但更符合您的问题描述)@Tim
    t:Sized
    是多余的:。@kazemakase:谢谢!如果你把它作为一个答案,我会接受的。@cornstales“这是一只虫子”很难成为一个好答案。。。但显然这是唯一的解决办法:(作为一种解决办法,你不能只在trait中使用函数而不是
    常量吗?
    ?它应该内联到同一个东西上。@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 }
    }