如何使用一系列参数初始化结构体

2023-12-27

在许多语言中,常见的构造函数习惯用法是使用如下伪代码的语法来初始化对象的值:

constructor Foo(args...) {
    for arg {
        object.arg = arg
    }
}

Rust 乍一看似乎也不例外。许多impl for a struct包含一个名为的构造函数new将一系列有序参数压缩到结构体的字段中:

struct Circle {
    x: i32,
    y: i32,
    radius: i32,
}

impl Circle {
    fn new(x: i32, y: i32, radius: i32) -> Circle {
        Circle { x: x, y: y, radius: radius }
    }
}

使用宏执行此操作可能看起来像zip!(Circle, 52, 32, 5)。它将按顺序将值压缩到以下字段中Circle. Both zip!(Circle, 52, 32) or zip!(Circle, 52, 32, 5, 100)会出现问题,但是像这样的宏将是一种非常灵活的方法,可以将值推送到任何结构的新实例上,而无需那么多样板文件。

有没有一种惯用的方法来简化这个样板?如何在不显式编写样板代码的情况下将一系列有序参数映射到结构的每个字段?


这对于宏来说是不可能的,原因很简单:宏不能凭空变出字段名称。

如果您愿意公开类型的详细信息,最简单的解决方案是将字段公开:

struct Circle {
    pub x: i32,
    pub y: i32,
    pub radius: i32,
}

fn main() {
    let circle = Circle { x: 3, y: 4, radius: 5 };
}

也就是说,没有need有一个构造函数,没有构造函数也能正常工作。

毕竟,如果构造函数除了传递值之外什么都不做,那么构造函数本身就毫无意义,不是吗?

如果您希望提供更短的初始化语法,您可以例如:

use std::convert::From;

impl From<(i32, i32, i32)> for Circle {
    fn from(t: (i32, i32, i32)) -> Circle {
        Circle { x: t.0, y: t.1, radius: t.2 }
    }
}

fn main() {
    let circle: Circle = (3, 4, 5).into();
}

通常,类型推断应该使您不必拼写出: Circle.

然而,我要指出的是,这更容易出错,因为在不注意的情况下交换两个参数要容易得多。您可能想坚持使用显式名称,或者引入显式类型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用一系列参数初始化结构体 的相关文章

随机推荐