У меня есть библиотека ввода-вывода с большой структурой State
, и я пишу функцию, которая требует двух этапов. На первом этапе затрагивается только класс читателя, но сайт вызова выбирает доступный только для чтения срез таблицы для передачи.
На втором этапе вся структура State
изменяется, но таблица только для чтения больше не нужна.
Я разделил функцию на две функции - и это работает, но когда я пытаюсь объединить эти функции, программа проверки заимствований перестает работать, когда я заменяю конкретный класс Vector
пользовательским признаком Slicable
Есть ли способ заставить process_with_table_fn
работать со значениями Slicable
в структуре состояния, а не непосредственно с векторами?
tl; dr Я бы хотел, чтобы fn what_i_want_to_work
скомпилировал, но вместо этого я получил только what_works
для сборки. Не подходит ли мое определение Slicable
для этого варианта использования? Почему конкретный тип действует лучше, чем черта?
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() {
}