我有一个数据结构Document,我想将其他 Rust 结构序列化为它。它基本上是HashMap内部字段的a ,但是它与数据库 API 交互,所以我肯定想将其他类型转换为那些Documents。
例如这个结构
struct Entry {
id: String,
user: String,
duration: u32,
location: (f64, f64),
}
Run Code Online (Sandbox Code Playgroud)
我已经Document使用Fromtrait进行了类型转换,但是这是一个额外的地方,当Entry结构改变时我必须修改。实现使用 aDocumentBuilder并且看起来像这样:
impl From<Entry> for Document {
fn from(entry: Entry) -> Self {
Document::builder()
.name(&entry.id) // set the name of the document
.field("user", entry.user) // add fields ...
.field("duration", entry.duration)
.field("location", entry.location)
.build() // build a Document
}
}
Run Code Online (Sandbox Code Playgroud)
该field方法可以将任何可以转换为 a 的值分配FieldValue给一个键。所以签名 …
假设我们有两个具有相同字段(和类型)的结构。
struct A {
pub data1: i32;
pub data2: string;
}
struct B {
pub data1: i32;
pub data2: string;
}
Run Code Online (Sandbox Code Playgroud)
要复制结构 A 和 B,我必须这样做
fn convert_A_to_B(a: A) -> B {
B {
data1: a.data1,
data2: a.data2
}
}
Run Code Online (Sandbox Code Playgroud)
我希望我能做类似的事情
B {
..a
}
Run Code Online (Sandbox Code Playgroud)
但这是不可能的,因为类型不同。是否有任何宏或语法可以对所有相同字段进行简单移动?
我有一个很大的结构Foo<Q>,并希望map它进入Foo<R>大多数字段不需要更新的地方.我本来希望使用..运算符,但这是一个类型错误,因为它们在技术上是不同的类型.
那是,给定:
struct Foo<T> {
a: usize,
b: usize,
t: T,
}
let q: Foo<Q>;
Run Code Online (Sandbox Code Playgroud)
我想写:
let r = Foo::<R> {
t: fixup(q.t),
..q
};
Run Code Online (Sandbox Code Playgroud)
但是,这给了我一个类型错误:
error[E0308]: mismatched types
|
3 | ..q
| ^ expected struct `R`, found struct `Q`
|
= note: expected type `Foo<R>`
found type `Foo<Q>`
Run Code Online (Sandbox Code Playgroud)
类型错误是合理的,因为在这种情况下类型可以被认为是模板.
我唯一的解决方法是完全写出转换,这很快就会变得丑陋:
let r = Foo::<R> {
a: q.a,
b: q.b,
t: fixup(q.t),
};
Run Code Online (Sandbox Code Playgroud)
这是一个带有完整测试用例的游乐场,包括编译错误和长格式.
这个地方有更好的语法,或者map为非平凡结构实现这些类似方法的更好方法吗?
鉴于以下两个结构:
pub struct RectangleRenderer {
canvas: Canvas,
origin: Point,
shape: Rectangle,
}
pub struct CircleRenderer {
canvas: Canvas,
center: Point,
shape: Circle,
}
Run Code Online (Sandbox Code Playgroud)
由于我来自爪哇,我会从中提取基类ShapeRenderer淘汰者和应用领域canvas,并origin到,虽然具体类型将继续把他们的领域shape。在这种情况下,Rust的最佳实践是什么,因为特征仅起到类似于界面的作用,因此不允许属性/字段?