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

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

问题描述

使用生锈1.2.0

问题

我还在学习Rust(来自Javascript背景)并试图找出一个结构是否可能 StructB 扩展现有的struct 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 来自外部货物我无法控制的包裹。

  • 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.

但是尝试实现它会导致此错误消息错误:虚拟结构已从语言。有些人稍后搜索,我发现它已经很快就按照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 或借出a & 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.

Traits

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.

as DK。提及,您可以选择实施 Deref DerefMut 。但是,我不同意这些特征应该以这种方式使用。我的论点类似于这样的论点,即使用经典的面向对象继承仅仅是为了代码重用是错误的。 赞成合成而不是继承=>赞成合成超过 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天全站免登陆