struct Vec2<T: Sub<Output = T> Add<Output = T> Copy> {
x: T,
y: T
}
impl<T: Sub<Output = T> Add<Output = T> Copy> Add for Vec2<T> {
type Output = Vec2<T>;
fn add(self, rhs: Self) -> Self::Output {
Vec2 {
x: self.x rhs.x,
y: self.y rhs.y
}
}
}
我是否需要<T: Sub<Output = T> Add<Output = T> Copy>每次都重寫這個不那么漂亮的方法,還是有另一種我不熟悉的更優雅的方法?
我知道一種hack可以通過這樣做來實作我想要的行為:
trait Numeric<T> : Sub<Output = T> Add<Output = T> Copy {}
macro_rules! add_impl {
($($t:ty)*) => ($(
impl Numeric<$t> for $t {}
)*)
}
add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
#[derive(Debug)]
struct Vec2<T: Numeric<T>> {
x: T,
y: T
}
impl<T: Numeric<T>> Add for Vec2<T> {
type Output = Vec2<T>;
fn add(self, rhs: Self) -> Self::Output {
Vec2 {
x: self.x rhs.x,
y: self.y rhs.y
}
}
}
這雖然部分解決了我的問題,但在我看來看起來更加混亂。
而且我知道“你不應該在結構定義中放置特征邊界”,但我真的希望編譯器在最終用戶嘗試時給出錯誤:
let v = Vec2 {
x: "Hello", // ERROR WANTED HERE
y: "World"
};
uj5u.com熱心網友回復:
特征別名是不穩定的,但如果您使用夜間工具鏈,您可以將長特征邊界別名為較短的,以便在您的impl塊中實際指定:
#![feature(trait_alias)]
use core::ops::{Add, Sub};
trait Numeric<T> = Sub<Output = T> Add<Output = T> Copy;
struct Vec2<T: Numeric<T>> {
x: T,
y: T
}
impl<T: Numeric<T>> Add for Vec2<T> {
type Output = Vec2<T>;
fn add(self, rhs: Self) -> Self::Output {
Vec2 {
x: self.x rhs.x,
y: self.y rhs.y
}
}
}
實作第二種方法的一種更正常的方法是僅impl Numeric針對滿足特征系結的所有型別,這消除了對宏的需要:
impl<T> Numeric<T> for T where T: Sub<Output = T> Add<Output = T> Copy {}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/510446.html
標籤:仿制药锈性状
