2017-09-10 2 views
2

Le système de type Rust ne généralise pas sur les tailles, mais avec type associated constants (nouveau dans Rust 1.20) Je pensais qu'il serait possible d'obtenir quelque chose en déclarant une taille constante sur un type.Les constantes associées au type Can peuvent-elles être utilisées pour généraliser les arguments de taille de tableau aux fonctions?

Étant donné les fonctions qui fonctionnent sur des matrices de taille fixe dans Rust, est-il possible/pratique d'utiliser des constantes de type pour déclarer des fonctions qui prennent des tailles arbitraires ou au moins une plage prédéfinie (1..32) .

Prenez ce petit API mathématiques par exemple:

// Cut down example of a math API 

// Could be changed at compile time, otherwise quite limiting. 
pub const DIMS: usize = 3; 

pub fn sq(a: f64) -> f64 { a } 

pub fn len_squared_vnvn(v0: &[f64; DIMS], v1: &[f64; DIMS]) -> f64 { 
    let mut d = 0.0; 
    for j in 0..DIMS { 
     d += sq(v0[j] - v1[j]); 
    } 
    return d; 
} 

fn imul_vn_fl(v0: &mut [f64; DIMS], f: f64) { 
    for j in 0..DIMS { 
     v0[j] *= f; 
    } 
} 

pourrait DIMS être déplacé à une constante de type associé pour que ...

  • Des fonctions telles que imul_vn_fl peuvent être utilisés avec de taille fixe arbitraire tableaux.
  • Prise en charge du passage de types matriciels de taille fixe primitive, par exemple: [f64; SOME_CONSTANT_NUMBER] ou, plus probablement, une conversion à coût nul vers un type qui enveloppe [f64; #] et définit la constante de type DIMS.
  • Utilisez std::convert::From/Into pour éviter d'avoir à écrire explicitement les conversions à chaque appel.
  • Le code généré doit être exactement aussi efficace que si des tailles constantes étaient utilisées (pas de vérification de la taille d'exécution).

Je me fais quelque chose comme ceci: (actuel)

// this would be a macro to avoid re-writing for every size. 
type f64v3 = u64; 
impl VectorSize for f64v3 { 
    const usize DIMS = 3; 
} 
// end macro 

fn example() { 
    let var: [f64; 3] = [0.0, 1.0, 2.0]; 
    imul_vn_fl(var, 0.5); 

    // ... 
} 
+0

Je n'ai pas de détails, mais il y a ceci: https://github.com/ fizyk20/generic-array – HTNW

+3

Désolé, les constantes au niveau du type sont une fonctionnalité hautement souhaitée qui n'est pas encore disponible: https://github.com/rust-lang/rfcs/issues/1038 – marcianx

+0

Rust 1.20 introduit des constantes associées au type , question éditée pour faire référence aux constantes de type * associated *, au lieu des constantes de type. – ideasman42

Répondre

1

La limitation des constantes associées est qu'ils ne peuvent pas être appelés types génériques. à savoir, suivant votre exemple, avec des constantes associées que vous pouvez faire ceci:

trait VectorSize { 
    const DIMS: usize; 
} 

impl VectorSize for u64 { 
    const DIMS: usize = 3usize; 
} 

fn imul_vn_fl(v0: &mut [f64; u64::DIMS], f: f64) { 
    for j in 0..u64::DIMS { 
     v0[j] *= f; 
    } 
} 

mais vous voulez finalement être en mesure de faire imul_vn_fl générique et avoir utiliser les DIMS qui est défini votre type. C'est là des constantes associées restent inférieurs (voir la première des « lacunes » dans https://github.com/rust-lang/rust/issues/29646)

// this does not compile, unfortunately; T must be a concrete type 
fn imul_vn_fl<T>(v0: &mut [f64; T::DIMS], f: f64) 
where 
    T:VectorSize 
{ 
    for j in 0..T::DIMS { 
     v0[j] *= f; 
    } 
} 

playground