lternativas `E` de curto-circuito do VBA [duplicado]
Esta pergunta já tem uma resposta aqui:
AndAlso / OrElse no VBA 7 respostasVBA não provoca curto-circuito
@VBA não suporta curtos-circuitos - aparentemente porque ele possui apenas operações bit a bit E / Ou / Não etc. De Especificação de idioma do VBA: "Operadores lógicos são operadores de dados simples que executam cálculos bit a bit em seus operandos." Nesse sentido, faz sentido que o VBA tenha sido projetado comtrue = &H1111
efalse = &H0000
: dessa maneira, as instruções lógicas podem ser avaliadas como operações bit a bi
A falta de curto-circuito pode causar problemas
Desempenho: oReallyExpensiveFunction()
sempre será executado quando esta declaração for avaliada, mesmo que não seja necessária pelo resultado do lado esquerdo da condição
If IsNecessary() And ReallyExpensiveFunction() Then '... End If
Errors: se MyObj for Nothing, essa declaração condicional resultará em um erro de tempo de execução porque o VBA ainda tentará verificar o valor deProperty
If Not MyObj Is Nothing And MyObj.Property = 5 Then '... End If
A solução que eu usei para implementar o comportamento de curto-circuito está aninhadaIf
s
If cond1 And cond2 Then
'...
End If
Torna-s
If cond1 Then
If cond2 Then
'...
End If
End If
Desta forma, as declarações If dão o comportamento de curto-circuito de não se preocupar em avaliarcond2
E second1
éFalse
.
Se houver uma cláusula Else, isso criará blocos de código duplicados
If Not MyObj Is Nothing And MyObj.Property = 5 Then
MsgBox "YAY"
Else
MsgBox "BOO"
End If
Torna-s
If Not MyObj Is Nothing Then
If MyObj.Property = 5 Then
MsgBox "YAY"
Else
MsgBox "BOO" 'Duplicate
End If
Else
MsgBox "BOO" 'Duplicate
End If
Existe uma maneira de reescreverIf
nstruções para preservar o comportamento de curto-circuito, mas evitar a duplicação de códig
Talvez com outra declaração de ramificação comoSelect Case
?
Para adicionar contexto à pergunta, aqui está o caso específico que estou analisando. Estou implementando uma tabela de hash que lida com colisões, encadeando-as em uma lista vinculada. O tamanho da matriz subjacente é imposto para ter uma potência de dois e os hashes são distribuídos no tamanho atual da matriz, truncando-os no comprimento apropriad
Por exemplo, suponha que o comprimento da matriz seja 16 (binário 10000). Se eu tiver uma chave que tenha hash em 27 (binário 11011), posso armazená-la na minha matriz de 16 slots mantendo apenas os bits dentro do limite do tamanho da matriz. O índice em que esse item seria armazenado é(hash value) And (length of array - 1)
que neste caso é(binary 11011) And (1111)
qual é1011
que é 11. O código hash real é armazenado junto com a chave no slo
Ao procurar um item na tabela de hash em uma cadeia, o hash e a chave devem ser verificados para determinar se o item correto foi encontrado. No entanto, se o hash não corresponder, não há motivo para verificar a chave. Eu esperava obter uma pequena quantidade intangível de desempenho aninhando os Ifs para obter o comportamento de curto-circuito:
While Not e Is Nothing
If keyhash = e.hash Then
If Key = e.Key Then
e.Value = Value
Exit Property
Else
Set e = e.nextEntry
End If
Else
Set e = e.nextEntry
End If
Wend
Você pode ver oSet...
é duplicado e, portanto, esta pergunt