Óxido compare la Opción <Vec <u8>> con la Opción <& [u8]>

8

¿Hay una manera elegante de comparar Option<Vec<u8>>por igualdad con Option<&[u8]>? (O equivalente con en Resultlugar de Option).

Timmmm
fuente

Respuestas:

10

Sólo se necesita para convertir Option<Vec<u8>>a Option<&[u8]>, el uso as_ref()y el Indexrasgo:

fn foo(a: Option<Vec<u8>>, b: Option<&[u8]>) -> bool {
    a.as_ref().map(|x| &x[..]) == b
}

A partir de Rust 1.40, puede usar as_deref():

fn foo(a: Option<Vec<u8>>, b: Option<&[u8]>) -> bool {
    a.as_deref() == b
}
Stargateur
fuente
Fuiste un poco más rápido, ok :)
Cerberus
@Cerberus No me importa, tu respuesta no usa la Vec::as_refmía, comprobada nuevamente, no hay un solo estilo en Rust;)
Stargateur
Yeat sería otra opción &**x.
Sven Marnach
11

Tal vez sea subóptimo, pero este código parece compilar:

fn cmp(first: Option<Vec<u8>>, second: Option<&[u8]>) -> bool {
    first.as_ref().map(Vec::as_ref) == second
}

Patio de recreo

Aquí hay dos transformaciones clave:

  1. La primera opción contiene el valor de propiedad, la segunda, una referencia. Entonces deberíamos ir deOption<T> (o &Option<T>) a Option<&T>, y esto se logra usando el as_refmétodo de Option.

  2. El primero Optionahora es válido &Vec<u8>y lo vamos a comparar &[u8]. Esto se maneja nuevamente por el as_refmétodo, ahora definido en el AsRef<[u8]>rasgo e implementado en Vec.

Cerbero
fuente
1
Ah, entonces ¿podría hacer lo mismo first.map(Vec::as_slice) == second?
Timmmm
Necesitará el primero de as_ref()todos modos: acabo de comprobar que no se compilará de otra manera. Pero sí, Vec::as_refy Vec::as_sliceparece ser intercambiable aquí.
Cerberus
¿Qué lenguaje es este? Etiquetarlo
alexherm
No entiendo, ¿qué pasa? La pregunta está etiquetada (y si no fuera así, le preguntarías al autor de la pregunta, no a mí).
Cerberus