我有一个实现如下:
use crate::queue::{Task, WorkQueue};
use digest::consts::U32;
use digest::generic_array::typenum::Pow;
use sha2::digest::generic_array::GenericArray;
use sha2::{Digest, Sha256};
use std::fmt::Write;
use std::ops::Add;
use std::sync;
pub type Hash = GenericArray<u8, U32>;
#[derive(Debug, Clone)]
pub struct Block {
pub prev_hash: Hash,
pub generation: u64,
pub difficulty: u8,
pub data: String,
pub proof: Option<u64>,
}
impl Block {
pub fn mine_range(self: &Block, workers: usize, start: u64, end: u64, chunks: u64) -> u64 {
// TODO: with `workers` threads, check proof values in the given range, breaking up
// into `chunks` tasks in a work queue. Return the first valid proof found.
// HINTS:
// - Create and use a queue::WorkQueue.
// - Use sync::Arc to wrap a clone of self for sharing.
unimplemented!()
}
pub fn mine_for_proof(self: &Block, workers: usize) -> u64 {
let range_start: u64 = 0;
let range_end: u64 = 8 * (1 << self.difficulty); // 8 * 2^(bits that must be zero)
let chunks: u64 = 2345;
self.mine_range(workers, range_start, range_end, chunks)
}
pub fn mine(self: &mut Block, workers: usize) {
self.proof = Some(self.mine_for_proof(workers));
}
}
struct MiningTask {
block: sync::Arc<Block>,
// TODO: more fields as needed
workers: usize
}
impl Task for MiningTask {
type Output = u64;
fn run(&self) -> Option<u64> {
// TODO: what does it mean to .run?
self.block.mine(self.workers);
let result = self.block.proof;
return result;
}
}
现在,如果我从run中取出返回状态,如下所示:
impl Task for MiningTask {
type Output = u64;
fn run(&self) -> Option<u64> {
// TODO: what does it mean to .run?
self.block.mine(self.workers);
let result = self.block.proof;
//return result;
}
}
然而这样的借款错误是不存在的:
impl Task for MiningTask {
type Output = u64;
fn run(&self) -> Option<u64> {
// TODO: what does it mean to .run?
self.block.mine(self.workers);
let result = self.block.proof;
return result;
}
}
它给我:无法借用Arc
中的数据,因为需要通过取消引用修改可变特性DerefMut
,但未对Arc<Block>
实现该特性
我不明白为什么返回某个东西会导致借用,我该如何修复这个问题?最好是没有互斥库还是没有借用?即使我尝试克隆自我,它仍然执行借用,我非常困惑。
1条答案
按热度按时间o2g1uqev1#
在MiningTask::run方法中,您尝试返回Block结构的proof字段。此字段存储在Option类型中,这意味着它要么是包含proof的Some值,要么是None值(如果尚未找到)。
当您尝试传回这个值时,编译器无法推断您是要传回证明字段的指涉,还是证明值的复本。若要传回证明字段的指涉,您必须使用Option::as_ref方法,将Option型别转换成指涉的Option。例如:
或者,您可以使用Option::copied方法将Option类型转换为基础类型(在本例中为u64)的Option,以传回校样值的副本。例如:
在您提供的程式码中,您已经完全移除了return陈述式。这表示MiningTask::run方法永远会传回None,因为传回型别是Option,而且方法主体中没有return陈述式。这不会造成借位错误,因为Block结构是 Package 在Arc中,允许对相同数据的多重指涉。
然而,以这种方式删除return语句意味着run方法将不返回mine方法找到的proof值。这可能不是您所希望的行为,这取决于您试图对MiningTask结构体做什么。
更新日期:
在您提供的代码中,run方法具有类型签名fn run(&self)-〉Option,这意味着它返回一个Option值。Option不是迭代器,因此不能与for循环语法一起使用。
如果你想使用for循环来迭代一个范围内可能的证明值,你需要改变run方法来返回一个迭代器而不是一个Option。下面是一个例子来说明你如何做到这一点:
在这个例子中,run方法返回一个迭代器,该迭代器产生指定范围内的证明值,按照给定的块大小步进。然后,你可以在for循环中使用这个迭代器来迭代证明值,并检查每个值的有效性。下面是一个例子: