【发布时间】: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<Self> 上。我指定T 来实现BitsIndex<T> 并且因为mask 是T 类型,编译器不应该在第8 行推断BitsIndex<T> 等于BitsIndex<Self> 吗?
更新
我想我明白了。下面的代码有效。
我之前的代码的一个问题是u32 不一定能转换为into 无论T 是什么。我们需要使用try_into,因此T需要绑定在TryFrom<u32>上。
然后将::<T> 添加到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