【问题标题】:cannot infer type for type parameter `I` declared on the associated function无法推断在关联函数上声明的类型参数“I”的类型
【发布时间】:2021-01-06 06:09:18
【问题描述】:
use intbits::{Bits, BitsIndex};
use num_traits::int::PrimInt;

fn setbit<T>(mask: &mut T)
where
    T: Bits + BitsIndex<T> + PrimInt,
{
    let pos = mask.trailing_zeros();
    mask.set_bit(pos.into(), false);
}

fn main() {
    let mut m = 0b0000_1000u8;
    setbit(&mut m);
    println!("{:08b}", m);
}

编译失败并出现错误:

mask.set_bit(pos.into(), false);
     ^^^^^^^ ---------- this method call resolves to `T`
     |
     cannot infer type for type parameter `I` declared on the associated function `set_bit`

我不确定为什么它不能推断类型参数。这里set_bit 要求它的第一个参数限制在特征BitsIndex&lt;Self&gt; 上。我指定T 来实现BitsIndex&lt;T&gt; 并且因为maskT 类型,编译器不应该在第8 行推断BitsIndex&lt;T&gt; 等于BitsIndex&lt;Self&gt; 吗?

更新

我想我明白了。下面的代码有效。

我之前的代码的一个问题是u32 不一定能转换为into 无论T 是什么。我们需要使用try_into,因此T需要绑定在TryFrom&lt;u32&gt;上。

然后将::&lt;T&gt; 添加到set_bit 有助于编译器推断出正确的类型。但我不确定为什么在这种情况下需要它。从上面的错误信息来看,编译器似乎已经可以推断出pos.into() 的类型是T

use intbits::{Bits, BitsIndex};
use num_traits::int::PrimInt;
use std::convert::TryInto;

fn setbit<T>(mask: &mut T)
where
    T: Bits + BitsIndex<T> + PrimInt + std::convert::TryFrom<u32>,
    <T as std::convert::TryFrom<u32>>::Error: std::fmt::Debug,
{
    let pos = mask.trailing_zeros();
    mask.set_bit::<T>(pos.try_into().unwrap(), false);
}

fn main() {
    let mut m = 0b0000_1000u8;
    setbit(&mut m);
    println!("{:08b}", m);
}

【问题讨论】:

  • 您不是将T 传递给set_bits,而是传递pos.into()pos 应该转换成什么?不能直接传pos吗?
  • @kmdreko trailing_zeros 返回u32 需要转换为T。我的原始代码错误地使用了into。它应该是try_into
  • 很难回答您的问题,因为它不包含minimal reproducible example。我们无法分辨代码中存在哪些 crate(及其版本)、类型、特征、字段等。如果您尝试在Rust Playground 上重现您的错误,如果可能的话,这将使我们更容易为您提供帮助,否则在全新的 Cargo 项目中,然后在edit 您的问题中包含附加信息。您可以使用Rust-specific MRE tips 来减少您在此处发布的原始代码。谢谢!
  • 很高兴您有问题的解决方案!您应该将其作为答案发布,而不是对您的问题进行编辑,然后可能会接受该答案。这样一来,问题就会在搜索结果中显示为已解决,人们可以对您的答案进行投票,而您的解决方案可能对未来遇到相同问题的人更有帮助。
  • @Shepmaster 我没有发布我的解决方案是一个答案,因为我只是通过反复试验才弄清楚的,没有真正理解它:) 我将阅读特定于 Rust 的 MRE 技巧以确保我的未来问题清晰易懂。感谢您的建议。

标签: rust


【解决方案1】:

您不需要强制 T 既是 Bits 又是它自己的索引 BitsIndex。由于trailing_zeroes() 总是返回u32,所以您需要做的就是限制u32 可以索引您的位。

fn setbit<T>(mask: &mut T)
where
    T: Bits + PrimInt,
    u32: BitsIndex<T>, // <----
{
    let pos = mask.trailing_zeros();
    mask.set_bit(pos, false);
}

【讨论】:

  • 这个解决方案更干净。我不知道特征绑定的左侧可能是这样的具体类型。谢谢。
猜你喜欢
  • 2020-11-03
  • 2023-03-08
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 2018-05-07
相关资源
最近更新 更多