我正在学习Rust几天,说实话,有些概念真的很难理解和应用。我开始重写一小部分组件,以比较Rust的传奇速度并通过一个具体项目学习。它是测量时间并在执行期间监视程序的组件。这将是另一个程序使用的动态库。
我的问题:
1)如何从&mut self创建Option<Box<T>>
? (fn add_son)
extern crate winapi;
extern crate user32;
extern crate kernel32;
struct KpiMethod{
element : String,
line : u32,
nb_occ : u32,
counter_start : i64,
counter_end : i64,
total_time: i64,
kpi_fils : Vec<KpiMethod>,
kpi_father : Option<Box<KpiMethod>>
}
impl KpiMethod {
pub fn new(_element: String, _line: u32, _father: Option<Box<KpiMethod>>) -> KpiMethod {
KpiMethod{
element : _element,
line : _line,
nb_occ : 1,
counter_start : get_counter(),
counter_end : 0,
total_time: 0,
kpi_fils : Vec::new(),
kpi_father : _father
}
}
pub fn add_son(&mut self, _element: String, _line: u32) -> KpiMethod{
//How create a Option<Box<KpiMethod>> of an existing KpiMethod (self) ?
let mut kpimet = KpiMethod::new(_element, _line, Some(Box::new(self)));
//Do I need a mutable self to push ?
self.kpi_fils.push(kpimet);
kpimet
}
pub fn find_son(&mut self, _element: String, _line: u32) -> Option<&KpiMethod> {
//which is the good and speed method to find a son with key (element,line) ?
for elem in self.kpi_fils.iter_mut() {
if elem.element == _element && elem.line == _line {
//why do I put a return here to fix error ?
return Some(elem)
}
}
None
}
}
pub struct KpiAgent{
kpi_Method : Vec<KpiMethod>,
current_Method : Option<Box<KpiMethod>>,
counter_start : i64,
counter_end : i64,
date_start : String,
date_end : String,
auto_consommation : u64,
}
impl KpiAgent {
pub fn new() -> KpiAgent {
KpiAgent{
kpi_Method: Vec::new(),
current_Method: None,
counter_start: 0,
counter_end: 0,
date_start: String::from(""),
date_end: String::from(""),
auto_consommation: 0
}
}
pub fn method_start(&mut self, element: String, line: u32){
match self.current_Method {
None => {
self.current_Method = Some(Box::new(KpiMethod::new(element, line, None)));
if self.counter_start == 0 {
self.counter_start = get_counter();
}
},
Some(method) => {
let metfils = method.find_son(element, line);
match metfils {
None => {
self.current_Method = Some(Box::new(method.add_son(element, line)));
},
Some(son) => {
son.nb_occ += 1;
son.counter_start = get_counter();
}
}
},
}
}
pub fn method_end(&mut self, element: String, line: u32){
match self.current_Method{
Some(met) => {
met.counter_end = get_counter();
self.counter_end = met.counter_end;
met.total_time += met.counter_end - met.counter_start;
self.current_Method = met.kpi_father;
}
}
}
}
pub fn get_counter() -> i64 {
let mut counter: i64 = 0;
unsafe{
kernel32::QueryPerformanceCounter(&mut counter);
}
counter
}
pub fn main() {
let mut met = KpiMethod::new("1c".to_string(), 1, None);
met.add_son("2c".to_string(),2);
met.add_son("3c".to_string(),3);
met.add_son("4c".to_string(),4);
let _toto = met.find_son("3c".to_string(),3);
match _toto{
None => println!("Not found"),
Some(x) => println!("{}",x.element),
}
let mut agent = KpiAgent::new();
agent.method_start("test".to_string(),2);
agent.method_end("test".to_string(),10);
}