Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.7k views
in Technique[技术] by (71.8m points)

rust - Is there syntax for moving fields between similar structs?

I have a big struct Foo<Q>, and want to map it into a Foo<R> where most of the fields don't need updating. I was hoping to use the .. operator for this, but it is a type error, as they are technically different types.

That is, given:

struct Foo<T> {
    a: usize,
    b: usize,
    t: T,
}

let q: Foo<Q>;

I would like to write:

let r = Foo::<R> {
    t: fixup(q.t),
    ..q
};

But, this gives me a type error:

error[E0308]: mismatched types
   |
 3 |         ..q
   |           ^ expected struct `R`, found struct `Q`
   |
   = note: expected type `Foo<R>`
              found type `Foo<Q>`

The type error is reasonable, as the types can be thought of as templates in this case.

The only workaround I have is to write out the transformation in full, which gets ugly quite quickly:

let r = Foo::<R> {
    a: q.a,
    b: q.b,
    t: fixup(q.t),
};

Here's a playground with a full test-case, including the compile error and the long-form.


Is there better syntax for this somewhere, or a better way to implement these map-like methods for non-trivial structs?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Is there syntax for moving fields between similar structs?

No. There is no such syntax. The current implementation of "struct update" (previously called "functional record update") syntax only allows the exact same type.

Is there better syntax for this somewhere, or a better way to implement these map-like methods for non-trivial structs?

No. The only suggestion I have is to destructure your original struct and then recreate it. You also don't need the ::<R> as it's inferred.

let Foo { a, b, c, d, e, t } = q;
let r = Foo {
    a,
    b,
    c,
    d,
    e,
    t: fixup(t),
};

See also:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...