2016-08-14 11 views
5

例えば、長さを2乗して配列を操作します。一般的な固定長配列で関数を定義する方法は?

これは、ジェネリック型(のようなf32f64)を持っていると便利ですが、あなたはまた、一般的な長さをしたいかもしれませんが、ないダイナミック長さ。

2つの引数をとる二乗関数の例を示します。

use std::ops::{Add, AddAssign, Sub, Mul}; 

const CAN_THIS_BE_GENERIC: usize = 2; 

fn squared_length<T>(
    a: &[T; CAN_THIS_BE_GENERIC], 
    b: &[T; CAN_THIS_BE_GENERIC] 
) -> T 
    where T: 
     Copy + 
     Add + 
     AddAssign + 
     Add<Output=T> + 
     Sub<Output=T> + 
     Mul<Output=T> 
{ 
    let mut d: T = a[0] - a[0]; // zero :(
    for (elem_a, elem_b) in a.iter().zip(b.iter()) { 
     let elem_dim: T = *elem_a - *elem_b; 
     d += elem_dim * elem_dim; 
    } 
    return d; 
} 

fn main() { 
    println!("Length A! {}", squared_length::<f64>(&[0.5, 3.5], &[10.0, 0.0])); 
    println!("Length B! {}", squared_length::<i32>(&[10, -6], &[4, 8])); 
    println!("Length C! {}", squared_length::<f32>(&[-3.0, 0.0], &[9.0, 0.0])); 
} 

現在のベクトルの長さはサイズが動的ますが、汎用ではない一般的な関数を定義することが可能です。2.

に設定され、同じ方法の種類は、一般的なことができますか?

+1

参照[ジェネリックの型パラメータを使用してメンバ配列のサイズを制御することはできますか?](http://stackoverflow.com/q/28136739/155423)およびすべてのリンクされた重複 – Shepmaster

答えて

7

いいえ、現在のRust 1.14では不可能です。これは(しばしば "タイプレベルの整数"と呼ばれる)長い要求の特徴ですが、まだRustでは利用できません。

これに関するいくつかのRFCがありました。最も最近のものは驚きとして来て、かなり有望です:RFC: const-dependent type system。しかし、たとえそれが受け入れられても、それは最終的に着陸するために複数のRustバージョンを取ることになります(例えば、非常には2016年に安定したコンパイラにすることはできません)。

type-numのようなタイプレベルの整数をシミュレートするいくつかのテンプレートがあります。使用可能なのですが、完全な代替手段とは言いません。

注意:タイプレベルの整数を使用する必要はない場合もあります。あなたの例は、動的なサイズでも動作します。さらに良い点:関数が非常に小さいため、インライン化される可能性が高く、オプティマイザはコンパイル時にすべてのサイズを把握できる可能性があります。したがって、パフォーマンスが型レベル整数を使用する唯一の理由であれば、必要ではないかもしれません。

1

まず、タイプレベルの数字が魅力的なAPIがたくさんありますが、関連するタイプをより直接的に使用することで柔軟性を高めることができます。

前記..

あり、ほぼ前述のタイプ-NUMを使用して、今、この権利を行うことができますgeneric-array crateはあるが、それはちょっと厄介取得しますが、あなたがここに欲しいものを行う必要があります。私はそれを自分で避ける。

rfcscompilerの両方で、これに向けて言語レベルの進捗状況があり、完全なconst依存型に関する継続的な議論があります。したがって、あまりにも遠い未来において、ジェネリックアレイクレートの使用はお勧めできません。

関連する問題