考虑以下代码:
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 类型系统有什么我没有得到的吗?
(请原谅我可能使用了一些 rust 术语错误,我是 rust 新手,来自 C++)
如果您将
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;
}