Die erste Regel für gute Manieren bei der Programmierung (oder eine der ersten) lautet: "Kopieren Sie den Code nicht." Verwenden Sie Funktionen und Vererbung.
Während bei Funktionen alles klar ist, ist die Vererbung komplizierter. Sie wissen wahrscheinlich, dass es in Rust keine direkte Vererbung gibt, aber es gibt Möglichkeiten, etwas Ähnliches zu erreichen. Ich werde dir davon erzählen.
impl dyn Trait
, , required ( , ) provided (, ). ? , - , - next()
. - map()
, filter()
, fold()
.. .
, RPG. , , , , , , , :
enum Damage{
Physical(f32),
Magic(f32)
}
trait Character{
fn get_magic_resistance(&self) -> f32;
fn get_physical_resistance(&self) -> f32;
fn set_hp(&mut self, new_value: f32);
fn get_hp(&self) -> f32;
fn get_type(&self) -> CharacterType;
fn get_dmg(&self) -> Damage;
}
impl dyn Character {
fn make_hurt(&mut self, dmg: Damage) {
match dmg{
Damage::Physical(dmg) => self.set_hp(self.get_hp() - dmg / self.get_physical_resistance().exp()),
Damage::Magic(dmg) => self.set_hp(self.get_hp() - dmg / self.get_magic_resistance().exp())
}
}
}
#[derive(Debug, Clone, Copy)]
enum CharacterType {
Mage,
Warrior,
Rogue
}
impl Default for CharacterType {
fn default() -> Self{
CharacterType::Warrior
}
}
#[derive(Default)]
struct Player{
ty: CharacterType,
phys_resist: f32,
mag_resist: f32,
hp: f32,
dmg: f32
}
impl Player {
pub fn new(ty: CharacterType, hp: f32, dmg: f32) -> Self {
Self{ ty, hp, dmg, .. Default::default() }
}
}
impl Character for Player{
#[inline]
fn get_magic_resistance(&self) -> f32 {
self.mag_resist
}
#[inline]
fn get_physical_resistance(&self) -> f32{
self.phys_resist
}
#[inline]
fn set_hp(&mut self, new_value: f32){
self.hp = new_value;
}
#[inline]
fn get_hp(&self) -> f32 {
self.hp
}
#[inline]
fn get_type(&self) -> CharacterType {
self.ty
}
fn get_dmg(&self) -> Damage{
match self.ty {
CharacterType::Mage => Damage::Magic(self.dmg),
_ => Damage::Physical(self.dmg)
}
}
}
struct EnemyWarrior{
ty: CharacterType,
phys_resist: f32,
mag_resist: f32,
hp: f32,
dmg: f32
}
impl Default for EnemyWarrior {
fn default() -> Self {
Self{
ty: CharacterType::Warrior,
phys_resist: 0.,
mag_resist: 0.,
hp: 10.,
dmg: 1.
}
}
}
impl Character for EnemyWarrior{
#[inline]
fn get_magic_resistance(&self) -> f32 {
self.mag_resist
}
#[inline]
fn get_physical_resistance(&self) -> f32{
self.phys_resist
}
#[inline]
fn set_hp(&mut self, new_value: f32){
self.hp = new_value;
}
#[inline]
fn get_hp(&self) -> f32 {
self.hp
}
fn get_type(&self) -> CharacterType {
CharacterType::Warrior
}
fn get_dmg(&self) -> Damage{
match self.ty {
CharacterType::Mage => Damage::Magic(self.dmg),
_ => Damage::Physical(self.dmg)
}
}
}
fn main(){
let mut player = Player::new(CharacterType::Warrior, 10., 1.);
let mut enemy = EnemyWarrior::default();
<dyn Character>::make_hurt(&mut enemy, player.get_dmg());
println!("{}", enemy.get_hp());
}
TL;DR 2 Character, 6 required 1 provided .
: " ?" , - , , required . -, , 6, , , - . , , - ?
Deref<Target=_>
Deref. , , , , , image : ImageBuffer Deref [P::Subpixel] , , , . Deref , .
use std::ops::Deref;
use std::ops::DerefMut;
enum Damage{
Physical(f32),
Magic(f32)
}
#[derive(Default)]
struct Character{
ty: CharacterType,
phys_resist: f32,
mag_resist: f32,
hp: f32,
dmg: f32
}
impl Character {
#[inline]
fn get_magic_resistance(&self) -> f32 {
self.mag_resist
}
#[inline]
fn get_physical_resistance(&self) -> f32{
self.phys_resist
}
#[inline]
fn set_hp(&mut self, new_value: f32){
self.hp = new_value;
}
#[inline]
fn get_hp(&self) -> f32 {
self.hp
}
#[inline]
fn get_type(&self) -> CharacterType {
self.ty
}
fn get_dmg(&self) -> Damage{
match self.ty {
CharacterType::Mage => Damage::Magic(self.dmg),
_ => Damage::Physical(self.dmg)
}
}
fn make_hurt(&mut self, dmg: Damage) {
match dmg{
Damage::Physical(dmg) => self.set_hp(self.get_hp() - dmg / self.get_physical_resistance().exp()),
Damage::Magic(dmg) => self.set_hp(self.get_hp() - dmg / self.get_magic_resistance().exp())
}
}
}
#[derive(Debug, Clone, Copy)]
enum CharacterType {
Mage,
Warrior,
Rogue
}
impl Default for CharacterType {
fn default() -> Self{
CharacterType::Warrior
}
}
#[derive(Default)]
struct Player(Character);
impl Player {
pub fn new(ty: CharacterType, hp: f32, dmg: f32) -> Self {
Self(Character{ ty, hp, dmg, .. Default::default() })
}
}
impl Deref for Player {
type Target = Character;
#[inline]
fn deref(&self) -> &Self::Target{
&self.0
}
}
impl DerefMut for Player {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target{
&mut self.0
}
}
struct EnemyWarrior(Character);
impl Default for EnemyWarrior {
fn default() -> Self {
Self(Character {
ty: CharacterType::Warrior,
phys_resist: 0.,
mag_resist: 0.,
hp: 10.,
dmg: 1.
})
}
}
impl Deref for EnemyWarrior {
type Target = Character;
#[inline]
fn deref(&self) -> &Self::Target{
&self.0
}
}
impl DerefMut for EnemyWarrior {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target{
&mut self.0
}
}
fn main(){
let mut player = Player::new(CharacterType::Warrior, 10., 1.);
let mut enemy = EnemyWarrior::default();
enemy.make_hurt(player.get_dmg());
println!("{}", enemy.get_hp());
}
, . , , , , , , , "", "".
. , "", , , "", . :
struct Child (Parent, ChildInner);
impl Child {
pub fn get_some_field_from_inner(&self) -> &ChildInner::Field {
&self.1.field
}
}
, , . , , / .
, . -, , , (, , ). Rust, , - , - . Deref, DerefMut , . , , . , self.1, . , , .
Das ist eigentlich alles, was ich zu diesem Thema sagen wollte. Vermisse ich etwas Schreiben Sie in die Kommentare, wenn Sie auch über dieses Thema besorgt sind. Ich möchte wissen, dass ich nicht der einzige bin, dem die Vererbung in Rust fehlt.