我有:
use std::ops::{Add, Div, Mul, Neg, Sub};
pub trait Hilbert: Add + Sub + Mul + Div + Neg + Mul<f64> + Div<f64> + Sized {
fn dot(&self, other: &Self) -> f64;
fn magnitude(&self) -> f64;
}
fn g<T: Hilbert>(x: T) -> f64 {
return (x * 2.0).dot(x);
}
......产生:
error[E0599]: no method named `dot` found for type `<T as std::ops::Mul<f64>>::Output` in the current scope
--> src/main.rs:9:22
|
9 | return (x * 2.0).dot(x);
| ^^^
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `dot`, perhaps you need to implement it:
candidate #1: `Hilbert`
我认为这意味着Rust无法保证具有特征T
的{{1}}类型的Hilbert
具有std::ops::Mul
类型的实现等于::Output
(a T
)。
但我知道(和/或希望要求)所有Hilbert
的情况都是如此,因此像Hilbert
这样的函数可以编写。
我会考虑为g()
std::ops::Mul::Output
Hilbert
...但这同时存在以下问题:(a)我无法部分实施&#34;特征,并将被迫为所有impl<T: Hilbert> Mul<f64> for T {
type Output = T;
}
生成函数Mul::mul()
的通用实现,但Hilberts
的实际实现将取决于Mul::mul()
的具体实现; (b)似乎我根本不允许写这个特性:
Hilbert
如何说服Rust error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter
--> src/main.rs:12:1
|
12 | / impl<T: Hilbert> Mul<f64> for T {
13 | | type Output = T;
14 | | }
| |_^
* Hilbert
- &gt; f64
必须举行?
答案 0 :(得分:2)
如何说服Rust
Hilbert * f64
- &gt;Hilbert
必须举行?
添加特征绑定<T as Mul<f64>>::Output: Hilbert
。但是,这样做会在您的设计中发现更多问题:
Hilbert.dot()
将第二个参数作为参考,而不是值。但是将相关行更改为(x * 2.0).dot(&x)
会导致另一个错误:“预期的关联类型,找到的类型参数”。dot
来Self
,但可能会有不同的Hilbert
实现。 dot
必须是通用的:fn dot<H: Hilbert>(&self, other: &H) -> f64;
(x * 2.0).dot(&x)
将不允许您使用x
两次,因为mul
按值获取其参数。您将需要添加一个绑定Mul<&'a Self>
才能传入引用(使用生命周期参数感染您的API)或使x
克隆(我不认为可复制)。< / LI>
醇>
将所有上述结果应用于此工作(?)可编译代码:
pub trait Hilbert: Add + Sub + Mul + Div + Neg + Mul<f64> + Div<f64> + Sized {
fn dot<H: Hilbert>(&self, other: &H) -> f64;
fn magnitude(&self) -> f64;
}
fn g<T: Hilbert + Clone>(x: T) -> f64
where
<T as Mul<f64>>::Output: Hilbert,
{
(x.clone() * 2.0).dot(&x)
}
如果Hilbert.dot
不应该是通用的,因为Hilbert
的不同实现不需要交互,代码可以稍微简单一些(就特征界限而言):
pub trait Hilbert:
Add + Sub + Mul + Div + Neg + Mul<f64, Output = Self> + Div<f64, Output = Self> + Sized
{
fn dot(&self, other: &Self) -> f64;
fn magnitude(&self) -> f64;
}
fn g<T: Hilbert + Clone>(x: T) -> f64 {
(x.clone() * 2.0).dot(&x)
}
然而,根据我对希尔伯特变换的了解,后一种情况似乎不太有用。