如何在Options和Into之间进行转换?

2024-01-04

我的项目中有一个结构A它在逻辑上与结构相关B来自不同的板条箱。两者内部都有一个可选的子结构(C / D).

假设对于这个例子,他们有这个结构定义:

struct D {
    name: Option<String>
}

struct B {
    spec: Option<D>
}

struct C {
    name: Option<String>
}

struct A {
    spec: Option<C>
}

现在我想实施Into- 特征A into B:

impl Into<D> for C {
    fn into(self) -> D {
        D {
            name: self.name
        }
    }
}

impl Into<B> for A {
    fn into(self) -> B {
        B {
            spec: self.spec.into()
        }
    }
}

但 Rust 不允许这样做:

error[E0277]: the trait bound `std::option::Option<D>: From<std::option::Option<C>>` is not satisfied
   --> src\model\k8s.rs:615:29
    |
615 |             spec: self.spec.into()
    |                             ^^^^ the trait `From<std::option::Option<C>>` is not implemented for `std::option::Option<D>`
    |
    = help: the following implementations were found:
              <std::option::Option<&'a T> as From<&'a std::option::Option<T>>>
              <std::option::Option<&'a mut T> as From<&'a mut std::option::Option<T>>>
              <std::option::Option<&'a tracing_core::span::Id> as From<&'a tracing::span::EnteredSpan>>
              <std::option::Option<&'a tracing_core::span::Id> as From<&'a tracing::span::Span>>
            and 10 others
    = note: required because of the requirements on the impl of `Into<std::option::Option<D>>` for `std::option::Option<C>`

虽然我提供了一个自定义实现Into on C它只检查From。我无法提供D是另一个板条箱。我必须这样写:

spec: if let Some(v) = self.spec { Some(v.into()) } else { None }

现在的问题是:我缺少更好的方法吗?如果不是的话,为什么这么麻烦into()选项?


问题是你正在打电话Into::into on the Option<C>类型而不是类型Option holds (C).

您可以使用Option::map https://doc.rust-lang.org/std/option/enum.Option.html#method.map对内部类型进行操作的方法Option:

impl Into<B> for A {
    fn into(self) -> B {
        B {
            spec: self.spec.map(Into::into)
        }
    }
}

没有毯子impl<T, U: Into<T>> Into<Option<T>> for Option<U>(或者From等价)在标准库中,这就是为什么你不能使用Into特质转向Option<T> into Option<U>直接在Option并且必须依靠Option::map或其他提取内部类型的方式(例如您的最后一个片段)。

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

如何在Options和Into之间进行转换? 的相关文章

随机推荐