Как я могу избежать использования небезопасного кода в коде ниже? Он предназначен для участия в библиотеке сущностей и компонентов. В более общем плане, есть ли способ включить типы возврата в Rust так, чтобы компилятор знал внутри блока, что тип возврата и тип сопоставления одинаковы?Есть ли способ включить типы возврата, чтобы компилятор знал, что тип возврата и тип сопоставления совпадают?
use std::any::{Any, TypeId};
use std::mem;
#[derive(Debug)] struct Health(f64);
#[derive(Debug)] struct Position([f64; 3]);
trait Entity {
fn get<'a, T: Any>(&self) -> Option<&'a T>;
}
#[derive(Debug)]
struct Pig {
health: Health,
position: Position,
}
impl Entity for Pig {
fn get<'a, T: Any>(&self) -> Option<&'a T> {
if TypeId::of::<T>() == TypeId::of::<Health>() {
Some(unsafe {mem::transmute(&self.health)})
} else if TypeId::of::<T>() == TypeId::of::<Position>() {
Some(unsafe {mem::transmute(&self.position)})
} else { None }
}
}
fn main() {
let waddles = Pig {
health: Health(2.0),
position: Position([1.0, 2.0, 3.0]),
};
println!("Waddles' Health: {:?}", waddles.get::<Health>());
}
Ничего себе, это приятно знать, я планировал изучать плагины компилятора с помощью этого проекта :) И, возможно, вы уже знали об этом, но вы можете избежать приведения с Any :: downcast_ref (& self.health), а это даже очиститель. Благодаря! – Shien
Возможно, это должен быть другой вопрос, но каким-либо образом это можно использовать в объектах признаков? Я имею в виду, я, наверное, должен был подумать об этом в первую очередь. – Shien
@Shien Это сложно. Вам также нужно будет вернуть компонент как объект признаков. Но, как вы сказали, достаточно другого вопроса - может быть, на форуме пользователя Rust, а не SO ... –