首页 > 解决方案 > 如何在具有类似 Into 特征的多个链式类型转换的代码中指导类型推断?

问题描述

我有一些由 protobuf 编译器生成的结构。它们具有相同的结构,我使它们像具有某些特征和宏的泛型一样。我还添加了一些代码,以便可以链接SingleResponse构造:

pub trait Response {
    type Success;
    type Fail;

    fn new_success(v: Self::Success) -> Self;
    fn new_fail(v: Self::Fail) -> Self;
}

pub trait IntoResponse<T>
where
    T: Response,
{
    fn into_response(self) -> T;
}

impl<T, U, K> IntoResponse<K> for Result<T, U>
where
    T: Into<K::Success>,
    U: Into<K::Fail>,
    K: Response,
{
    fn into_response(self) -> K {
        match self {
            Ok(v) => K::new_success(v.into()),
            Err(v) => K::new_fail(v.into()),
        }
    }
}

struct SingleResponse<T> {
    v: T,
}

trait IntoSingleResponse
where
    Self: std::marker::Sized,
{
    fn into_single_response(self) -> SingleResponse<Self>;
}

impl<T: std::marker::Sized> IntoSingleResponse for T {
    fn into_single_response(self) -> SingleResponse<Self> {
        SingleResponse { v: self }
    }
}

这说明了问题:

struct ConcreteSuccess {}
struct ConcreteFail {}
struct ConcreteResponse {}

impl Response for ConcreteResponse {
    type Success = ConcreteSuccess;
    type Fail = ConcreteFail;

    fn new_success(_v: Self::Success) -> Self {
        // Logic not important
        ConcreteResponse {}
    }
    fn new_fail(_v: Self::Fail) -> Self {
        ConcreteResponse {}
    }
}

fn get_result() -> Result<ConcreteSuccess, ConcreteFail> {
    Ok(ConcreteSuccess {})
}

// works as expected
fn return_response() -> ConcreteResponse {
    get_result().into_response()
}

// works as expected
fn return_single_response() -> SingleResponse<ConcreteResponse> {
    return_response().into_single_response()
}

// this function does not compile
fn return_single_response_v_2() -> SingleResponse<ConcreteResponse> {
    get_result().into_response().into_single_response()
}
error[E0282]: type annotations needed
  --> src/lib.rs:80:18
   |
80 |     get_result().into_response().into_single_response()
   |     -------------^^^^^^^^^^^^^--
   |     |            |
   |     |            cannot infer type for type parameter `T` declared on the trait `IntoResponse`
   |     this method call resolves to `T`
   |
   = note: type must be known at this point

我如何return_single_response_v_2编译?

标签: rustgeneric-programming

解决方案


推荐阅读