2017-08-18 5 views
0

J'essaye de créer une fonction qui prend deux itérateurs comme paramètres et itére sur les articles par référence. Chaque élément Iterator doit implémenter PartialEq.À quoi fait référence Rhs dans un message d'erreur du compilateur à propos de PartialEq?

Ma première tentative a été:

fn compute<T: Iterator>(first: T, second: T, len: usize) -> usize 
where 
    T::Item: std::cmp::PartialEq, 
{ 
    // ... 
} 

Cette compile mais itère (pour autant que je comprends) et non par référence, mais en valeur et le compilateur se plaint d'un mouvement quand itérer.

Ma deuxième tentative a été quelque chose comme:

fn compute<'a, T>(first: T, second: T, len: usize) -> usize 
where 
    T: Iterator<Item = &'a std::cmp::PartialEq>, 
{ 
    //... 
} 

entraînant une erreur du compilateur:

error[E0393]: the type parameter `Rhs` must be explicitly specified 
--> src/main.rs:3:28 
    | 
3 |  T: Iterator<Item = &'a std::cmp::PartialEq>, 
    |       ^^^^^^^^^^^^^^^^^^^ missing reference to `Rhs` 
    | 
    = note: because of the default `Self` reference, type parameters must be specified on object types 

Qu'est-ce que le (côté droit?) Rhs le compilateur fait référence à ici signifie? Pourquoi ai-je besoin d'une référence? Comment est-ce que je passe un Iterator basé sur la référence bornée dans une fonction?

+0

Tous les itérateurs n'ont pas d'éléments auxquels ils peuvent renvoyer des références. Je pense que vous devez montrer comment vous essayez d'utiliser le premier 'compute' et l'erreur du compilateur; on ne sait pas pourquoi cela ne fonctionnerait pas. – trentcl

+0

Lorsque vous écrivez 'PartialEq' après le' Item = ', il est dans un contexte de type *, donc il est interprété comme un objet trait, pas comme un trait. – Rufflewind

+0

Vous avez raison sur l'abréviation: LHS est utilisé pour Left Hand Side et RHS pour Right Side Side quand on parle d'opérateurs binaires (je préfère personnellement les désigner comme Gauche et Droite quand les deux sont dans la portée, parce que je n'aime pas les identifiants différant par une seule lettre). –

Répondre

4

PartialEq est un trait qui vous permet de comparer deux valeurs. Ces deux valeurs et non doivent être du même type! Le type génériqueRhs est utilisé pour spécifier le type avec lequel nous comparons. Par défaut, la valeur de Rhs est le même que le type qui est comparé à:

pub trait PartialEq<Rhs = Self> 
where 
    Rhs: ?Sized, 

Dans ce cas, vous demandez en fait que la valeur soit iterator l'objet trait &PartialEq. Comme le message d'erreur indique:

because of the default Self reference, type parameters must be specified on object types

Nous pourrions préciser:

fn compute<'a, T>(first: T, second: T, len: usize) -> usize 
where 
    T: Iterator<Item = &'a std::cmp::PartialEq<i32>>, 

ou

fn compute<'a, T: 'a>(first: T, second: T, len: usize) -> usize 
where 
    T: Iterator<Item = &'a std::cmp::PartialEq<&'a T>>, 

but iterates (as far as I understand) not by reference but by value

Il est tout à fait possible à itérer par référence. Rappelez-vous que T est tout type et que i32, &i32, et &mut i32 sont tous les types. Votre premier exemple est la formulation de la signature que j'utiliserais:

fn compute<T: Iterator>(first: T, second: T, len: usize) -> usize 
where 
    T::Item: std::cmp::PartialEq, 
{ 
    42 
} 

fn main() { 
    let a = [1, 2, 3]; 
    let b = [4, 5, 6]; 

    compute(a.iter(), b.iter(), 1); 
    compute(a.iter(), b.iter(), 2); 
    compute(a.iter(), b.iter(), 3); 
}