Ich habe eine IO-Bibliothek, die eine große Struktur State
hat und ich schreibe eine Funktion, die zwei Phasen benötigt. In der ersten Phase wird nur die Leserklasse berührt, aber die Call-Site wählt eine schreibgeschützte Tabellenscheibe zum Übergeben.Wie aktualisiere ich meine Slicable-Eigenschaft, um die Borrow-Checker in wiederholten Aufrufen zu erfüllen
In der zweiten Phase wird die gesamte State
-Struktur modifiziert, aber die schreibgeschützte Tabelle wird nicht mehr benötigt.
Ich habe die Funktion in zwei Funktionen aufgeteilt - und das funktioniert, aber wenn ich versuche, diese Funktionen zu kombinieren, bricht der borrow checker, als ich eine konkrete Vector
Klasse mit einem benutzerdefinierten Merkmale Slicable
Ist ersetzen Gibt es einen Weg process_with_table_fn
auf Slicable
Werte in der State-Struktur statt direkt auf Vektoren zu machen?
tl; dr Ich möchte Fn what_i_want_to_work
kompilieren, aber stattdessen habe ich nur what_works
zu bauen. Ist meine Eigenschaftsdefinition für Slicable
schlecht für diesen Anwendungsfall? Warum funktioniert der Betontyp besser als das Merkmal?
pub struct MemReader {
buf : [u8; 1024],
off : usize,
}
pub struct Vector<'a> {
buf : &'a [u32],
}
trait Slicable {
fn slice(self : &Self) -> &[u32];
}
impl<'a> Slicable for Vector<'a> {
fn slice(self : &Self) -> &[u32]{
return self.buf;
}
}
impl MemReader {
fn read(self : &mut Self, how_much : usize, output : &mut u8) -> bool {
if self.off + how_much > self.buf.len() {
return false;
}
self.off += how_much;
*output = self.buf[self.off - 1];
return true;
}
}
pub struct State<'a> {
pub mr : MemReader,
pub translation_tables : [Vector<'a>; 4],
pub other_tables : [Vector<'a>; 4],
pub state : i32,
}
fn process_first(mr : &mut MemReader, table : &[u32]) -> (bool, u32) {
let mut temp : u8 = 0;
let ret = mr.read(8, &mut temp);
if !ret {
return (false, 0);
}
return (true, table[temp as usize]);
}
fn process_second(s : &mut State, ret_index : (bool, u32), mut outval : &mut u8) -> bool {
let (ret, index) = ret_index;
if ! ret {
return false;
}
s.state += 1;
return s.mr.read(index as usize, &mut outval);
}
pub fn process_with_table_fn(mut s : &mut State, table : &[u32], mut outval : &mut u8) -> bool {
let ret = process_first(&mut s.mr, table);
return process_second(&mut s, ret, &mut outval);
}
macro_rules! process_with_table_mac(
($state : expr, $table : expr, $outval : expr) => {
process_second(&mut $state, process_first(&mut $state.mr, &$table), &mut $outval)
};
);
pub fn what_works(mut s : &mut State) {
let mut outval0 : u8 = 0;
let _ret0 = process_with_table_fn(&mut s, &s.other_tables[2].buf[..], &mut outval0);
}
/*
pub fn what_i_want_to_work(mut s : &mut State) {
let mut outval0 : u8 = 0;
let ret0 = process_with_table_fn(&mut s, s.other_tables[2].slice(), &mut outval0);
// OR
let mut outval1 : u8 = 0;
//let ret1 = process_with_table_mac!(s, s.other_tables[2].slice(), outval1);
}
*/
fn main() {
}