【发布时间】:2020-06-27 16:24:01
【问题描述】:
尝试实现一个通用的 Vec 实现 std::ops::Add 特征。我希望实现在添加时自动转换向量的基础类型,以便我可以执行以下操作:
let u: Vec3<i32> = Vec3 { x: 1, y: 2, z: 3 };
let v: Vec3<i8> = Vec3 { x: 2, y: 3, z: 4 };
let w = u + v;
在呼叫现场不使用.into()。我已经实现了 From 特征(它会自动添加 Into 实现)并且它在一个简单的函数上运行良好:
fn foo<T: Into<Vec3<i32>>>(input: T) -> Vec3<i32> {
input.into()
}
let v: Vec3<i8> = Vec3 { x: 2, y: 3, z: 4 };
println!("{:?}", foo(v));
链接到非编译示例here。是否可以对运算符右侧参数的类型进行约束,如果可以,如何?
#![allow(dead_code)]
use std::convert::{From};
use std::ops::{Add};
#[derive(Debug)]
struct Vec3<T> {
x: T,
y: T,
z: T,
}
impl<T: Add<Output=T>> Add<U: Into<Vec3<i32>>> for Vec3<T> {
type Output = Vec3<T>;
fn add(self, rhs: U) -> Self::Output {
let rhs_converted: Vec3<T> = rhs.into();
Vec3 {
x: self.x.add(rhs_converted.x),
y: self.y.add(rhs_converted.y),
z: self.z.add(rhs_converted.z),
}
}
}
impl From<Vec3<i8>> for Vec3<i32> {
fn from(input: Vec3<i8>) -> Self {
Vec3 {
x: input.x.into(),
y: input.y.into(),
z: input.z.into(),
}
}
}
fn foo<T: Into<Vec3<i32>>>(input: T) -> Vec3<i32> {
input.into()
}
fn main() {
let u: Vec3<i32> = Vec3 { x: 1, y: 2, z: 3 };
let v: Vec3<i8> = Vec3 { x: 2, y: 3, z: 4 };
let w = u + v;
// println!("{:?}", foo(v));
println!("{:?}", w);
}
【问题讨论】:
-
请注意,自动类型转换不被视为惯用的 Rust,并且在语言及其标准库中有意避免。
标签: generics rust polymorphism traits parametric-polymorphism