lternativas `E` de curto-circuito do VBA [duplicado]

Esta pergunta já tem uma resposta aqui:

AndAlso / OrElse no VBA 7 respostas

VBA 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á aninhadaIfs

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 reescreverIfnstruçõ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

questionAnswers(3)

yourAnswerToTheQuestion