Existem várias declarações semelhantes em VB6: Let, Set, LSet e RSet.
Let é usado para atribuição de variáveis gerais:
Copie o código do código da seguinte forma:
[Deixe] varname = expressão
Na maioria dos casos, omitimos Let e atribuímos valores diretamente com o sinal de igual, por isso muitas pessoas nem sabem da existência de Let.
Set é usado para atribuição de objetos, apontando a variável para o objeto e aumentando a contagem de referências do objeto. Muitas pessoas não sabem o que é contagem de referências.
Então, para que é usado o LSet? À primeira vista parece ser uma combinação de Let e Set, mas não é. O L em LSet é a abreviatura de Left e sua contraparte é RLet. Você me pergunta como eu sei que L é a abreviatura de Esquerda? O documento diz:
Copie o código do código da seguinte forma:
Instrução LSet
Alinha à esquerda uma string dentro de uma variável de string ou copia uma variável de um tipo definido pelo usuário para outra variável de um tipo diferente definido pelo usuário.
Instrução RSet
Alinha à direita uma string dentro de uma variável de string.
LSet tem mais uma função que RSet. Não vamos examinar isso primeiro. Vamos examinar a mesma parte primeiro. O que isso significa? Na verdade, não entendo só de ler a documentação. Vamos testar na prática:
Copie o código do código da seguinte forma:
Subprincipal()
Escurecer URL como string
Dim é como string
Deixe url = "//www.VeVB.COm"
s = String$(20, "*")
LSet s = url
Debug.Prints
RSet s = url
Debug.Prints
Finalizar sub
Saída (observe os espaços):
Copie o código do código da seguinte forma:
//www.VeVB.COm
//www.VeVB.COm
Na verdade, está alinhado à esquerda e à direita, e nosso asterisco * é substituído por um espaço. Qual é a utilidade disso? Na minha opinião, parece que pode ser realmente inútil, não sei o que o designer pensou.
No entanto, outra função do LSet é muito poderosa: ela pode copiar uma variável de tipo definida pelo usuário para outra variável de tipo definida pelo usuário. O que isto significa?
Deixe-me dar um exemplo. Você sabe o endereço IP? O IP retornado pelo ping do Baidu aqui é 61.135.169.125. O endereço IP neste formato é apenas para visualização humana. O IP é, na verdade, representado por um número inteiro de 32 bits dentro do computador. Como usar o VB para converter o endereço IP no formato xxx.xxx.xxx.xxx em um número inteiro de 32 bits? Depois de algum Google, você pode escrever um código semelhante a este:
Copie o código do código da seguinte forma:
Subprincipal()
Debug.Print IPToLong("61.135.169.125")
Finalizar sub
Função privada IPToLong (IPStr As String) As Long
Dim Str() como string, HEXStr como string, TempStr como string
Dim x tão longo
Str = Dividir(IPStr, ".")
HEXStr = ""
Para x = 0 para UBound(Str)
TempStr = Hex(Str(x))
HEXStr = HEXStr & String(2 - Len(TempStr), "0") & TempStr
Próximo x
IPToLong = CLng("&H" & HEXStr)
Função final
O código funciona bem, tudo bem, mas podemos escrever um código mais "avançado" usando a instrução LSet:
Copie o código do código da seguinte forma:
Tipo privado myBytes
B1 como byte
B2 como byte
B3 como byte
B4 como byte
Tipo final
Tipo privado myLong
Val tão longo
Tipo final
'Por Demônio
'http://VeVB.COm
Função pública IP2Long (ip As String) As Long
Dim a() como string
Dim b Como myBytes
Dim l Como myLong
a = Divisão(ip, ".")
'Nota Little-Endian
b.B1 = CByte(a(3))
b.B2 = CByte(a(2))
b.B3 = CByte(a(1))
b.B4 = CByte(a(0))
LDefinir l = b
IP2Long = l.Val
Função final
Use LSet para copiar uma variável do tipo myBytes para uma variável do tipo myLong. É muito bom e poderoso. Dê uma olhada no código assembly gerado:
Copie o código do código da seguinte forma:
00401A0E lea eax, dword ptr [ebp-0x20]; endereço da variável b;
00401A11 empurrar eax
00401A12 lea eax, dword ptr [ebp-0x14]; endereço da variável l;
00401A15 empurrar eax
00401A16 empurrar 0x4
00401A18 chama __vbaCopyBytes; jmp para MSVBVM60.__vbaCopyBytes
O que é chamado é __vbaCopyBytes em MSVBVM60.DLL O primeiro parâmetro é o byte a ser copiado, o segundo parâmetro é o endereço de destino e o terceiro parâmetro é o endereço de origem. É semelhante à função memcpy na biblioteca padrão C. exceto que a ordem dos parâmetros é diferente e sua implementação interna nada mais é do que instruções de transferência de strings em assembly:
Copie o código do código da seguinte forma:
72A1A0F3 > mov ecx, dword ptr [esp+0x4]
72A1A0F7 empurre esi
72A1A0F8 mov esi, dword ptr [esp+0x10]
72A1A0FC enviar edição
72A1A0FD mov edi, dword ptr [esp+0x10]
72A1A101 mov eax,ecx
72A1A103 mov edx, edi
72A1A105 shrecx, 0x2
72A1A108 rep movs dword ptr es:[edi], dword ptr [esi]
72A1A10A mov ecx, eax
72A1A10C mov eax, edx
72A1A10E e ecx, 0x3
72A1A111 rep movs byte ptr es:[edi], byte ptr [esi]
72A1A113 papadi
72A1A114 pop esi
72A1A115 retn 0xC
Deve-se notar que a documentação nos alerta:
Copie o código do código da seguinte forma:
Aviso Usar LSet para copiar uma variável de um tipo definido pelo usuário em uma variável de um tipo diferente definido pelo usuário não é recomendado. Copiar dados de um tipo de dados no espaço reservado para um tipo de dados diferente pode causar resultados imprevisíveis.
Quando você copia uma variável de um tipo definido pelo usuário para outro, os dados binários de uma variável são copiados para o espaço de memória da outra, independentemente dos tipos de dados especificados para os elementos.
Usar LSet para copiar variáveis de tipo definidas pelo usuário não é recomendado e pode levar a resultados inesperados (como estruturas desalinhadas); portanto, não use a instrução LSet a menos que você saiba o que está fazendo.