我如何解决所需的类型注释无法推断类型参数“T”的类型?编译此代码需要什么类型的注释?
How do i resolve type annotations needed cannot infer type for type parameter `T` ? What type annotation is needed to compile this code?
区块链结构定义,它定义了一个类型,我使用该类型
pub struct Blockchain<T = SledDb> {
pub storage: T,
pub chain: Vec<Block>,
pub tip: Arc<RwLock<String>>,
pub height: AtomicUsize,
pub mempool: Mempool,
pub wallet: Wallet,
pub accounts: Account,
pub stakes: Stake,
pub validators: Validator,
}
此代码正在检查 stake 是否为 valid.The 用于挖掘块的代码,错误由 is_staking_valid 函数排除。我不知道它要求什么类型,因为我已经指定了一个。
impl<T: Storage> Blockchain<T> {
pub fn is_staking_valid(
balance: u64,
difficulty: u32,
timestamp: i64,
prev_hash: &String,
address: &String,
) -> bool {
let base = BigUint::new(vec![2]);
let balance_diff_mul = base.pow(256) * balance as u32;
let balance_diff = balance_diff_mul / difficulty as u64;
let data_str = format!("{}{}{}", prev_hash, address, timestamp.to_string());
let sha256_hash = digest(data_str);
let staking_hash = BigUint::parse_bytes(&sha256_hash.as_bytes(), 16).expect("msg");
staking_hash <= balance_diff
}
pub fn mine_block(&mut self, data: &str) -> Option<Block> {
if self.mempool.transactions.len() < 2 {
info!("Skipping mining because no transaction in mempool");
return None;
}
let balance = self
.stakes
.get_balance(&self.wallet.get_public_key())
.clone();
let difficulty = self.get_difficulty();
info!("New block mining initialized with difficulty {}", difficulty);
let timestamp = Utc::now().timestamp();
let prev_hash = self.chain.last().unwrap().hash.clone();
let address = self.wallet.get_public_key();
if Blockchain::is_staking_valid(balance, difficulty, timestamp, &prev_hash, &address){
let block = self.create_block(&data, timestamp);
self.storage.update_blocks(&prev_hash, &block, self.height.load(Ordering::Relaxed));
Some(block)
} else {
None
}
}
}
请在下面找到编译错误
error[E0282]: type annotations needed
--> src/blocks/chain.rs:173:12
|
173 | if Blockchain::is_staking_valid(balance, difficulty, timestamp, &prev_hash, &address){
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
For more information about this error, try `rustc --explain E0282`.
最小化示例:
pub struct Blockchain<T> {
pub storage: T,
}
impl<T> Blockchain<T> {
pub fn is_staking_valid() {
todo!()
}
pub fn mine_block(&mut self) {
Blockchain::is_staking_valid();
}
}
此错误的原因是 Blockchain::<T1>::is_staking_valid
和 Blockchain::<T2>::is_staking_valid
以及编译器所关注的两个独立的、完全不相关的函数。是的,它们有相同的代码,是的,它们将被优化器删除重复数据,但这并不一定是这种情况——例如,如果这个函数使用了一些在 T
:[=33 上可用的关联项=]
trait Stakable {
const IS_VALID: bool;
}
impl Stakable for () {
const IS_VALID: bool = false;
}
impl Stakable for i32 {
const IS_VALID: bool = true;
}
struct Blockchain<T> {
pub _storage: T,
}
impl<T: Stakable> Blockchain<T> {
fn validate() {
if !T::IS_VALID {
panic!("Type is not valid");
}
}
}
fn main() {
// This panics - we catch this panic and show that it has indeed happened
std::panic::catch_unwind(|| Blockchain::<()>::validate()).unwrap_err();
// This executes successfully
Blockchain::<i32>::validate();
}
由于可能存在歧义,编译器拒绝自行选择并强制您明确选择。
所以,您有几种可能的方法:
- 使
is_staking_valid
成为自由函数,而不是 Blockchain
的关联函数。在这种情况下,它将无法依赖于 Blockchain
的类型参数,因此调用将是明确的。
- 调用
Self::is_staking_valid
而不是 Blockchain::is_staking_valid
。在这种情况下,Self
将被替换为 Blockchain::<T>
,T
取自当前执行的方法;这将再次解决歧义。
- 将
is_staking_valid
设为 Blockchain
上的方法,即使其接收 &self
,并通过 self.is_staking_valid()
. 调用它
- 不推荐,但仍然可行,- 使
is_staking_valid
成为 Blockchain<T>
上的关联函数,用于 某些特定的 T
,例如:
pub struct Blockchain<T> {
pub storage: T,
}
impl Blockchain<()> {
// Note - no free type parameters here!
pub fn is_staking_valid() {
todo!()
}
}
impl<T> Blockchain<T> {
pub fn mine_block(&mut self) {
// Here, `Blockchain` is `Blockchain::<()>` - the method is set
Blockchain::is_staking_valid();
}
}
区块链结构定义,它定义了一个类型,我使用该类型
pub struct Blockchain<T = SledDb> {
pub storage: T,
pub chain: Vec<Block>,
pub tip: Arc<RwLock<String>>,
pub height: AtomicUsize,
pub mempool: Mempool,
pub wallet: Wallet,
pub accounts: Account,
pub stakes: Stake,
pub validators: Validator,
}
此代码正在检查 stake 是否为 valid.The 用于挖掘块的代码,错误由 is_staking_valid 函数排除。我不知道它要求什么类型,因为我已经指定了一个。
impl<T: Storage> Blockchain<T> {
pub fn is_staking_valid(
balance: u64,
difficulty: u32,
timestamp: i64,
prev_hash: &String,
address: &String,
) -> bool {
let base = BigUint::new(vec![2]);
let balance_diff_mul = base.pow(256) * balance as u32;
let balance_diff = balance_diff_mul / difficulty as u64;
let data_str = format!("{}{}{}", prev_hash, address, timestamp.to_string());
let sha256_hash = digest(data_str);
let staking_hash = BigUint::parse_bytes(&sha256_hash.as_bytes(), 16).expect("msg");
staking_hash <= balance_diff
}
pub fn mine_block(&mut self, data: &str) -> Option<Block> {
if self.mempool.transactions.len() < 2 {
info!("Skipping mining because no transaction in mempool");
return None;
}
let balance = self
.stakes
.get_balance(&self.wallet.get_public_key())
.clone();
let difficulty = self.get_difficulty();
info!("New block mining initialized with difficulty {}", difficulty);
let timestamp = Utc::now().timestamp();
let prev_hash = self.chain.last().unwrap().hash.clone();
let address = self.wallet.get_public_key();
if Blockchain::is_staking_valid(balance, difficulty, timestamp, &prev_hash, &address){
let block = self.create_block(&data, timestamp);
self.storage.update_blocks(&prev_hash, &block, self.height.load(Ordering::Relaxed));
Some(block)
} else {
None
}
}
}
请在下面找到编译错误
error[E0282]: type annotations needed
--> src/blocks/chain.rs:173:12
|
173 | if Blockchain::is_staking_valid(balance, difficulty, timestamp, &prev_hash, &address){
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
For more information about this error, try `rustc --explain E0282`.
最小化示例:
pub struct Blockchain<T> {
pub storage: T,
}
impl<T> Blockchain<T> {
pub fn is_staking_valid() {
todo!()
}
pub fn mine_block(&mut self) {
Blockchain::is_staking_valid();
}
}
此错误的原因是 Blockchain::<T1>::is_staking_valid
和 Blockchain::<T2>::is_staking_valid
以及编译器所关注的两个独立的、完全不相关的函数。是的,它们有相同的代码,是的,它们将被优化器删除重复数据,但这并不一定是这种情况——例如,如果这个函数使用了一些在 T
:[=33 上可用的关联项=]
trait Stakable {
const IS_VALID: bool;
}
impl Stakable for () {
const IS_VALID: bool = false;
}
impl Stakable for i32 {
const IS_VALID: bool = true;
}
struct Blockchain<T> {
pub _storage: T,
}
impl<T: Stakable> Blockchain<T> {
fn validate() {
if !T::IS_VALID {
panic!("Type is not valid");
}
}
}
fn main() {
// This panics - we catch this panic and show that it has indeed happened
std::panic::catch_unwind(|| Blockchain::<()>::validate()).unwrap_err();
// This executes successfully
Blockchain::<i32>::validate();
}
由于可能存在歧义,编译器拒绝自行选择并强制您明确选择。
所以,您有几种可能的方法:
- 使
is_staking_valid
成为自由函数,而不是Blockchain
的关联函数。在这种情况下,它将无法依赖于Blockchain
的类型参数,因此调用将是明确的。 - 调用
Self::is_staking_valid
而不是Blockchain::is_staking_valid
。在这种情况下,Self
将被替换为Blockchain::<T>
,T
取自当前执行的方法;这将再次解决歧义。 - 将
is_staking_valid
设为Blockchain
上的方法,即使其接收&self
,并通过self.is_staking_valid()
. 调用它
- 不推荐,但仍然可行,- 使
is_staking_valid
成为Blockchain<T>
上的关联函数,用于 某些特定的T
,例如:
pub struct Blockchain<T> {
pub storage: T,
}
impl Blockchain<()> {
// Note - no free type parameters here!
pub fn is_staking_valid() {
todo!()
}
}
impl<T> Blockchain<T> {
pub fn mine_block(&mut self) {
// Here, `Blockchain` is `Blockchain::<()>` - the method is set
Blockchain::is_staking_valid();
}
}