为什么 rust 编译器无法找出在通用模板特化中调用的适当函数?

问题描述 投票:0回答:1

考虑以下代码:

trait A {}

struct X { p1: i32 }
struct Y { p1: i32, p2: i32 }

impl A for X {}
impl A for Y {}

struct Z<T> where T: A {
    data: T
}

impl Z<X> {
    fn new(p1: i32) -> Self {
        Self { data: X { p1: p1 } }
    }
}

impl Z<Y> {
    fn new(p1: i32, p2: i32) -> Self {
        Self { data: Y { p1: p1, p2: p2 } }
    }
}

像这样一起创建

Z<X>
Z<Y>
时:

let zx: Z<X> = Z::new(1);
let zy: Z<Y> = Z::new(2, 3);

编译器抛出错误,大概是说

Z::new()
存在两次:

error[E0034]: multiple applicable items in scope
  --> main.rs:33:23
   |
33 |     let zx: Z<X> = Z::new(1);
   |                       ^^^ multiple `new` found
   |

但是,当像这样创建

Z<X>
Z<Y>
时:

let zx: Z<X> = Z::<X>::new(1);
let zy: Z<Y> = Z::<Y>::new(2, 3);

一切都编译得很好。

现在我想知道: 如果给定类型注释就应该知道这些信息,为什么还需要手动指定

<X>
<Y>
的用法?

作为后续问题: 为什么

new()
在Z中似乎存在两次,但在
Z<X>
Z<Y>
中分别只存在一次? 关于 Rust 类型系统有什么我没有得到的吗?

  • rustc 版本 1.77.1

(请原谅我可能使用了一些 rust 术语错误,我是 rust 新手,来自 C++)

generics rust
1个回答
0
投票

如果您将

new
函数及其参数类型包装在工厂特征中,它就会起作用。尽管它需要单个构造函数参数,但需要一个元组而不是多个参数:

trait A {}

struct X {
    p1: i32,
}
struct Y {
    p1: i32,
    p2: i32,
}

impl A for X {}
impl A for Y {}

struct Z<T>
where
    T: A,
{
    data: T,
}

trait ZFactory {
    type Args;

    fn new(args: Self::Args) -> Self;
}

impl ZFactory for Z<X> {
    type Args = i32;
    fn new(p1: i32) -> Self {
        Self { data: X { p1 } }
    }
}

impl ZFactory for Z<Y> {
    type Args = (i32, i32);

    fn new(args: Self::Args) -> Self {
        Self {
            data: Y {
                p1: args.0,
                p2: args.1,
            },
        }
    }
}

fn main() {
    let zx: Z<X> = Z::new(1);
    let zy: Z<Y> = Z::new((2, 3));

    let zxa: &dyn A = &zx.data;
    let zxb: &dyn A = &zy.data;
}
© www.soinside.com 2019 - 2024. All rights reserved.