Но как я могу сделать такую вещь в Rust?Возможно ли это даже без использования небезопасного кода?До сих пор у меня есть дерево
Чтобы сделать то же самое напрямую , вам нужно будет использовать небезопасный код.Функция std::mem::transmute
делает именно то, что вы хотите.Проблема в том, что макет структуры в Rust не гарантирован, поэтому следующее поведение обычно будет неопределенным:
use std::mem;
let list_link: Option<Box<ListNode<_>>> = unsafe { mem::transmute(tree_node) };
Однако вы можете сделать это безопасно, сделав макет структур прогнозируемым, используя представление C
:
#[repr(C)]
struct TreeNode<'a, T> {
left_child: BinaryTreeLink<'a, T>,
right_child: BinaryTreeLink<'a, T>,
data : &'a T,
}
#[repr(C)]
struct ListNode<'a, T> {
before: ListLink<'a, T>,
after: ListLink<'a, T>,
data : &'a T,
}
Вам также понадобится применить #[repr(C)]
к определениям внутренних типов ListLink
и BinaryTreeLink
.
А как насчет того, чтобы вообще избежать небезопасного кода?Если вы пишете функции преобразования, которые потребляют исходных данных, оптимизатор должен иметь возможность превратить их в неиспользуемые, потому что он знает, что никакой другой код не может ссылаться на эту память.
<'a, T> impl From<ListNode<'a, T>> for TreeNode<'a, T> {
fn from(other: ListNode<'a, T>) -> ListNode<'a, T>> {
ListNode {
before: other.left_child,
after: other.right_child,
data: other.data,
}
}
}
Вы должны обязательно проверить это, чтобы убедиться, но оптимизатор обладает всей информацией, которая ему необходима, чтобы превратить это в бездействие, и весьма вероятно, что это произойдет.