rust traits

rust - Diferencia entre<T: Rasgo> y donde T: Rasgo



traits (1)

Los límites de rasgos definidos dentro de una cláusula where son un superconjunto de los límites de rasgos declarados en línea. El estilo en línea existía antes de la cláusula where ; la cláusula where fue introducida en RFC 135 :

Agregar cláusulas where , que proporcionan un medio más expresivo de especificar límites de parámetros de rasgos. [...] La notación de límites existentes se mantendría como azúcar sintáctica para las cláusulas where .

Aquí hay una lista de limitaciones con la sintaxis de límites actual que se supera con la sintaxis where:

  • No puede expresar límites en otra cosa que no sea el tipo de parámetros. Por lo tanto, si tiene una función genérica en T , puede escribir T:MyTrait para declarar que T debe implementar MyTrait , pero no puede escribir Option<T> : MyTrait o (int, T) : MyTrait . Estas formas son menos comunes pero aún importantes.

  • No funciona bien con los tipos asociados. Esto se debe a que no hay espacio para especificar el valor de un tipo asociado. Otros idiomas usan cláusulas where (o algo análogo) para este propósito.

  • Es simplemente difícil de leer. La experiencia ha demostrado que a medida que crece el número de límites, la sintaxis actual se vuelve difícil de leer y formatear.

Desde entonces, también puedes usar límites de rasgos de mayor rango ( for <''a> ... ) en una cláusula where :

fn foo<T, U>() where // higher-ranked trait bounds for<''a> T: SomethingElse<''a>, // Bound not directly on the generic type i32: From<U>, T: Iterator, // Bound on an associated type T::Item: Clone, // Just really long U: ReallyLong + AnotherReallyLong + WowReallyLong, {}

Si sus necesidades se pueden cumplir con los límites de rasgos en línea, entonces no hay impacto en su código. Si necesita los poderes adicionales que solo permiten, entonces necesita usar where .

Mi estilo personal es usar siempre la forma where . Tener una sola forma que también sea más fácil de git diff cuando agregue nuevos límites me valdrá la línea de código adicional.

En los documentos para el rasgo de Send , veo ambos

impl<T> Send for LinkedList<T> where T: Send,

y

impl<T: Send> Send for LinkedList<T>

¿Cuál es la diferencia entre estas dos sintaxis y cómo impactaría mi código si estuviera escribiendo declaraciones impl para mi propio rasgo?