2017-01-20 9 views
0

などの型との関係を指定します。は、私は、次の仕事のようなものを作りたいの形質またはマクロ

use std::ops::Add; 

trait CanBeAdded: Sized where f64: Add<Self> {} 

fn add2<X: CanBeAdded>(x: X) {} 

fn main() {} 

上記のコンパイルに失敗します。

error[E0277]: the trait bound `f64: std::ops::Add<X>` is not satisfied 
--> src/main.rs:5:1 
    | 
5 | fn add2<X: CanBeAdded>(x: X) {} 
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Add<X>` is not implemented for `f64` 
    | 
    = help: consider adding a `where f64: std::ops::Add<X>` bound 
    = note: required by `CanBeAdded` 

Playground link

私は」特定のimplの存在を特性によってアサートしようとしています。つまり、X: CanBeAddedf64: Add<X>を意味します。私はこのような機能のwhere句に境界を追加することができますが:

fn add2<X>(x: X) where f64: Add<X> { } 

それは扱いにくくなるので、私はそれらの多くを持っていると私は何度も境界を繰り返さないことを好むだろう。これには良い解決策がありますか?たとえば、一連のwhere句に展開されるマクロを含めることは可能ですか?

+0

重複(HTTP [新しい特性を定義するために、複数の特性を結合する方法があります]:// stackoverflowのは。 com/q/26983355/155423) – Shepmaster

+0

ええと、2つ目のタイプの 'f64'が含まれているので違います.2つ以上のタイプの関係があります。私はそれをもっと明示すべきですか? – yong

+0

@DK 'impl CanBeAdded for X where f64:Add {}'という行を追加すると、 'imp'はどうなるでしょうか? https://play.rust-lang.org/?gist=59b0932a780fdcaf21848de9d310621a&version=nightly&backtrace=0 – yong

答えて

0

ランダムタイプXf64: Add<X>であることは実際にはほとんどありません。

f64が組み込まれていると、Addの実装を定義できる唯一のモジュールは、Addが定義されているモジュールです。

  • impl Add<f64> for f64
  • impl<'a> Add<&'a f64> for f64

そして、それがすべてです:私たちはlisted implementations here確認することができます。


さらに、それがすべて必要な場合は、特性を別々に定義することができます。

まず、新しいマーカー形質を定義する。その後

trait ReverseAdd<T> { type Output; } 

、我々は毛布の実装を追加し、自動的にAddを実装する任意のタイプのための形質を実装することが、関係を逆転:それは全くの方法を持っているとして、それ自体でかなり面白くないです

impl<T, U> ReverseAdd<T> for U where T: Add<U> { 
    type Output = <T as Add<U>>::Output; 
} 

そして最後に、我々はバウンドとしてそれを使用する:の

fn add2<X: ReverseAdd<f64>>(x: X) { 
}