Ferrugem compara a Opção <Vec <u8>> com a Opção <& [u8]>

8

Existe uma maneira elegante de comparar Option<Vec<u8>>igualdade com Option<&[u8]>? (Ou equivalente a em Resultvez de Option.)

Timmmm
fonte

Respostas:

10

Você só precisa converter Option<Vec<u8>>para Option<&[u8]>, usando as_ref()e Indexcaracterística:

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

A partir do Rust 1.40, você pode usar as_deref():

fn foo(a: Option<Vec<u8>>, b: Option<&[u8]>) -> bool {
    a.as_deref() == b
}
Stargateur
fonte
Você era apenas um pouco mais rápido, ok :)
Cerberus
@Cerberus Eu não me importo, seu uso resposta Vec::as_refmeu não, provou novamente que não há um e somente um estilo em Rust;)
Stargateur
Outra opção seria &**x.
Sven Marnach 14/10/19
11

Talvez seja abaixo do ideal, mas esse código parece compilar:

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

Parque infantil

Existem duas transformações principais aqui:

  1. A primeira opção contém o valor de propriedade, a segunda - uma referência. Portanto, devemos ir de Option<T>(ou &Option<T>) para Option<&T>e isso é alcançado usando o as_refmétodo de Option.

  2. O primeiro Optionagora é válido &Vec<u8>e vamos compará-lo &[u8]. Isso é tratado novamente pelo as_refmétodo, agora definido na AsRef<[u8]>característica e implementado em Vec.

Cerberus
fonte
1
Ah, então eu poderia fazer de forma equivalente first.map(Vec::as_slice) == second?
Timmmm
Você precisará do primeiro de as_ref()qualquer maneira - acabei de verificar, caso contrário não será compilado. Mas sim, Vec::as_refe Vec::as_sliceparece ser intercambiável aqui.
Cerberus
Que língua é essa? Marque-o.
Alexherm 17/10/19
Eu não entendo, o que há de errado? A pergunta está marcada (e, se não estivesse, você perguntaria ao solicitante, não a mim).
Cerberus