一个结构是否可以扩展现有结构并保留所有字段? [英] Is it possible for one struct to extend an existing struct, keeping all the fields?

查看:19
本文介绍了一个结构是否可以扩展现有结构并保留所有字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 rust 1.2.0

问题

我仍在学习 Rust(来自 Javascript 背景)并试图弄清楚是否有可能让一个结构 StructB 扩展现有的结构 StructA 使得 StructB 具有 StructA 上定义的所有字段.

I'm still in the process of learning Rust (coming from a Javascript background) and am trying to figure out if it is possible for one struct StructB to extend an existing struct StructA such that StructB has all the fields defined on StructA.

在 Javascript(ES6 语法)中,我基本上可以做这样的事情...

In Javascript (ES6 syntax) I could essentially do something like this...

class Person {
    constructor (gender, age) {
        this.gender = gender;
        this.age = age;
    }
}
class Child extends Person {
    constructor (name, gender, age) {
        super(gender, age);
        this.name = name;
    }
}

约束

  • StructA 来自我无法控制的外部 cargo 包.
  • StructA is from an external cargo package that I have no control over.

当前进展

我发现了这篇关于单一继承的博文这听起来正是我需要的.

I found this blog post on single-inheritance which sounds like exactly what I need.

但尝试实现它会导致此错误消息error: virtual structs has been removed from the language.后来一些搜索,我发现它是 根据 RFC-341 实施然后删除 相当快.

But trying to implement it resulted in this error message error: virtual structs have been removed from the language. Some searching later and I found out that it had been implemented and then removed per RFC-341 rather quickly.

还发现了这个关于使用特性的线程,但由于 StructA 来自外部货物包,我认为我不可能将其变成特征.

Also found this thread about using traits, but since StructA is from an external cargo package I don't think it is possible for me to turn it into a trait.

那么在 Rust 中实现这一目标的正确方法是什么?

So what would be the correct way to accomplish this in Rust?

推荐答案

没有完全匹配的东西.我想到了两个概念.

There is nothing that exactly matches that. There are two concepts that come to mind.

  1. 结构组成

  1. Structural composition

struct Person {
    age: u8,
}

struct Child {
    person: Person,
    has_toy: bool,
}

impl Person {
    fn new(age: u8) -> Self {
        Person { age: age }
    }

    fn age(&self) -> u8 {
        self.age
    }
}

impl Child {
    fn new(age: u8, has_toy: bool) -> Self {
        Child { person: Person::new(age), has_toy: has_toy }
    }

    fn age(&self) -> u8 {
        self.person.age()
    }
}

fn main() {
    let p = Person::new(42);
    let c = Child::new(7, true);

    println!("I am {}", p.age());
    println!("My child is {}", c.age());
}

您可以简单地将一个结构嵌入到另一个结构中.内存布局很好而且紧凑,但是你必须手动将所有方法从 Person 委托给 Child 或借出一个 &Person.

You can simply embed one struct into another. The memory layout is nice and compact, but you have to manually delegate all the methods from Person to Child or lend out a &Person.

特性

trait SayHi {
    fn say_hi(&self);
}

struct Person {
    age: u8,
}

struct Child {
    age: u8,
    has_toy: bool,
}

impl SayHi for Person {
    fn say_hi(&self) {
        println!("Greetings. I am {}", self.age)
    }
}

impl SayHi for Child {
    fn say_hi(&self) {
        if self.has_toy {
            println!("I'm only {}, but I have a toy!", self.age)
        } else {
            println!("I'm only {}, and I don't even have a toy!", self.age)
        }
    }
}

fn greet<T>(thing: T)
    where T: SayHi
{
    thing.say_hi()
}

fn main() {
    let p = Person { age: 42 };
    let c = Child { age: 7, has_toy: true };

    greet(p);
    greet(c);
}

当然,您可以将这两个概念结合起来.

You can combine these two concepts, of course.

作为 DK.提到,你可以选择实现DerefDerefMut.但是,我不同意应该以这种方式使用这些特征.我的论点类似于将经典的面向对象继承仅用于代码重用是错误的论点.优先组合而不是继承"=>优先组合而不是 Deref".但是,我确实希望有一种语言功能可以实现简洁的委托,从而减少组合的烦恼.

As DK. mentions, you could choose to implement Deref or DerefMut. However, I do not agree that these traits should be used in this manner. My argument is akin to the argument that using classical object-oriented inheritance simply for code reuse is the wrong thing. "Favor composition over inheritance" => "favor composition over Deref". However, I do hold out hope for a language feature that enables succinct delegation, reducing the annoyance of composition.

这篇关于一个结构是否可以扩展现有结构并保留所有字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆