![](/img/trans.png)
[英]The trait `std::ops::Fn<(char,)>` is not implemented for `T`
[英]How do I specify the expected result of a `std::ops::Mul` in a trait bound?
我有:
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无法保证具有特征Hilbert
T
类型具有std::ops::Mul
的实现,其::Output
类型等于T
(一个Hilbert
)。
但是我知道(和/或希望要求)所有Hilbert
都是这种情况,因此可以编写g()
类的函数。
我会觉得IMPL std::ops::Mul::Output
为Hilbert
:
impl<T: Hilbert> Mul<f64> for T {
type Output = T;
}
...但是这同时存在一些问题,即(a)我无法“部分实现”特征,并且将被迫为所有Hilberts
生成函数Mul::mul()
的泛型实现,但实际实现是Mul::mul()
取决于Hilbert
的具体实现; (b)似乎根本不允许我写这个特征:
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
* f64
> Hilbert
必须持有的Rust?
我如何说服
Hilbert * f64
>Hilbert
必须持有的Rust?
您添加一个以<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
克隆(我认为可复制并不适用)。 将以上所有结果应用于此可工作的可编译代码:
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
实现不需要交互Hilbert.dot
不通用,则代码可以稍微简单一些(就特征界限而言):
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)
}
但是,根据我对希尔伯特变换的了解,后一种情况似乎不太有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.