1
以下のコードで安全でないコードを使用しないようにするにはどうすればよいですか?エンティティコンポーネントシステムライブラリの一部であることを意味します。より一般的には、戻り値の型と一致する型が同じであることをコンパイラがブロック内で知る方法で、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>());
}
うわー、それは、私はこのプロジェクトでコンパイラプラグインを学ぶ上で、計画:)そしてええと、あなたはおそらく既に知っていた知ってうれしいですが、あなたもある代わりに、どれ:: downcast_ref(&self.health)、とキャストを避けることができますクリーナー。ありがとう! – Shien
これはおそらく別の質問でしょうが、これは形質オブジェクトで使用することができますか?私はおそらく、まずそのことを考えていたはずです。 – Shien
@Shien難しいです。コンポーネントを特性オブジェクトとして返す必要があります。しかし、あなたが言ったように、それは別の質問のために十分です - たぶん、そうではなく、Rustユーザーフォーラムに... –