【问题标题】:Is there syntax for moving fields between similar structs?是否有在相似结构之间移动字段的语法?
【发布时间】:2019-05-16 19:35:50
【问题描述】:

我有一个很大的结构Foo<Q>,并且想将map 转换成一个Foo<R>,其中大部分字段都不需要更新。我希望为此使用 .. 运算符,但这是一个类型错误,因为它们在技术上是不同的类型。

也就是说,给定:

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

let q: Foo<Q>;

我想写:

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

但是,这给了我一个类型错误:

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

类型错误是合理的,因为在这种情况下可以将类型视为模板。

我唯一的解决方法是完整地写出转换,这很快就会变得丑陋:

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

这里是a playground with a full test-case,包括编译错误和长格式。


在某处是否有更好的语法,或者有更好的方法来为非平凡的结构实现这些map-like 方法?

【问题讨论】:

    标签: syntax rust


    【解决方案1】:

    是否有在相似结构之间移动字段的语法?

    没有。没有这样的语法。 “结构更新”(以前称为“功能记录更新”)语法的当前实现只允许完全相同的类型。

    在某处是否有更好的语法,或者有更好的方法来为非平凡的结构实现这些类似映射的方法?

    没有。我唯一的建议是解构您的原始结构,然后重新创建它。你也不需要::&lt;R&gt;,因为它是推断出来的。

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

    另见:

    【讨论】:

    • 我很高兴这只是每个 other Rust 论坛的副本,而不是 StackOverflow 的。感谢您的链接和解构建议。
    • @FauxFaux:我对匹配语句也有类似的杀戮想法,例如match optionT { Some(t) =&gt; Some(makeItU(t)), other =&gt; other },它抱怨other 不是Option&lt;U&gt; 类型,即使“None”在两者中都是相同的原子案例;或者类似地具有不同的生命周期......当剩余的变体都是'static时。希望这种剪纸会及时变得更好:)
    • @MatthieuM。看起来它不会被任何现有的 RFC 所涵盖,如果您想修复它,可能值得在更高的级别上提高?对于Option 的情况,我怀疑人们会告诉你使用map,或者明确地使用None =&gt; None,这两种方法都可以。
    • @FauxFaux:我不确定是否有任何“解决”问题的愿望。它基本上需要依赖于路径的类型,这是对任何语言的重要补充。至于Option,我只是用它来演示,因为它很熟悉;在自定义枚举上没有 map
    猜你喜欢
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2012-02-12
    • 1970-01-01
    相关资源
    最近更新 更多