Я оборачиваю библиотеку C в Rust, и многие из ее функций принимают параметры в виде указателей на структуры, которые сами часто имеют указатели на другие структуры. В интересах сокращения накладных расходов я хотел бы предоставить возможность кэшировать результаты маршалинга данных Rust в структуры C.
Вот пример того, как библиотека C может ожидать некоторые параметры:
#[repr(C)]
struct Foo {
x: i32,
y: f32
}
#[repr(C)]
struct Bar {
p_foo: *const Foo,
z: bool
}
И как я себе представляю, как будет выглядеть «кэшированная» версия:
struct Cached {
foo: Option<Foo>,
bar: Bar
}
Поле p_foo
в bar
должно указывать на значение Some
в пределах foo
или нулевой указатель, если есть None
.
Проблема здесь, конечно, в том, что если бы значение Cached
нужно было переместить, то прямое memcpy
было бы неуместным, а bar.p_foo
нужно было бы дополнительно перенаправить. Это было бы легко обеспечить в C++ с его определяемой семантикой перемещения, но предлагает ли Rust решение, кроме «не устанавливать bar.p_foo
, пока оно не будет использовано»? Хотя это, безусловно, будет работать таким образом, я не думаю, что эти кэшированные значения будут перемещаться чаще, чем (или даже близко к частоте) их повторного использования, и для настройки этих указатели, особенно если вложенность/цепочка глубокая/длинная. Я также предпочел бы не Box
подструктуры в куче.
Чтобы уточнить, вот что я могу написать на C++, что я хотел бы воспроизвести в Rust:
struct Foo {
int x;
float y;
};
struct Bar {
Foo const*pFoo;
bool z;
};
// bear with me while I conjure up a Maybe for C++
class Cached {
public:
// would have appropriate copy constructor/assignment
Cached(Cached &&other) {
m_foo = other.m_foo;
m_bar = other.m_bar;
if(m_foo.isJust()) {
m_bar.pFoo = &m_foo.value();
} // else already nullptr
}
// similar move assignment
private:
Maybe<Foo> m_foo;
Bar m_bar;
};
Cached
должно быть перемещено - я чувствую, что вы не предоставляете достаточно информации. Что могло бы сохранить указатель наbar.p_foo
, который станет недействительным при его перемещении? Что-то вроде это вообще кажется полезным? - person Shepmaster   schedule 24.03.2016bar.p_foo
это указатель, который будет признан недействительным, если объект будет перемещен, поскольку он указывает на поле (часть a) самой структуры. Я поясню, написав эквивалент того, что я хочу на С++. - person jmegaffin   schedule 24.03.2016