В VB6 есть несколько похожих операторов: Let, Set, LSet и RSet.
Let используется для присвоения общих переменных:
Скопируйте код кода следующим образом:
[Let] имя_переменной = выражение
В большинстве случаев мы опускаем Let и присваиваем значения напрямую со знаком равенства, поэтому многие люди даже не знают о существовании Let.
Set используется для присвоения объекта, указания переменной на объект и увеличения счетчика ссылок на объект. Многие люди не знают, что такое подсчет ссылок.
Так для чего же используется LSet? На первый взгляд кажется, что это комбинация Let и Set, но это не так. L в LSet — это сокращение от Left, а его аналог — RLet. Вы спрашиваете меня, откуда я знаю, что L — это сокращение от Left? Что сказано в документе:
Скопируйте код кода следующим образом:
Оператор LSet
По левому краю выравнивает строку внутри строковой переменной или копирует переменную одного определяемого пользователем типа в другую переменную другого определяемого пользователем типа.
Оператор RSet
По правому краю выравнивает строку внутри строковой переменной.
У LSet есть еще одна функция, чем у RSet. Давайте сначала не будем рассматривать ее, а сначала рассмотрим одну и ту же часть. Обе функции используются для выравнивания строки по левому (правому) краю строковой переменной. Что это значит? На самом деле, я этого не понимаю, просто читая документацию. Давайте проверим это на практике:
Скопируйте код кода следующим образом:
Подглавная()
Тусклый URL-адрес в виде строки
Dim как строка
Пусть url="//www.VeVB.COm"
s = String$(20, "*")
LSet s = URL
Debug.Print s
RSet s = URL-адрес
Debug.Print s
Конец субтитра
Вывод (обратите внимание на пробелы):
Скопируйте код кода следующим образом:
//www.VeVB.COM
//www.VeVB.COM
Он действительно выравнивается по левому и правому краю, а наша звездочка * заменяется пробелом. Какой в этом толк? На мой взгляд, кажется, что это действительно может быть бесполезно, не знаю, что подумал дизайнер.
Однако есть еще одна очень мощная функция LSet: она может копировать переменную пользовательского типа в другую переменную пользовательского типа. Что это значит?
Позвольте мне привести вам пример. Знаете ли вы IP-адрес? IP-адрес, полученный при пинге Baidu, равен 61.135.169.125. IP-адрес в этом формате предназначен только для просмотра человеком. IP-адрес на самом деле представлен 32-битным целым числом внутри компьютера. Как использовать VB для преобразования IP-адреса в формате xxx.xxx.xxx.xxx в 32-битное целое число? После некоторого Google вы можете написать код, подобный этому:
Скопируйте код кода следующим образом:
Подглавная()
Debug.Print IPToLong("61.135.169.125")
Конец субтитра
Частная функция IPToLong (IPStr As String) до тех пор, пока
Dim Str() как строка, HEXStr как строка, TempStr как строка
Тусклый х как долго
Str = Split(IPStr, ".")
HEXStr = ""
Для x = 0 To UBound(Str)
TempStr = Hex(Str(x))
HEXStr = HEXStr & String(2 - Len(TempStr), "0") & TempStr
Следующий х
IPToLong = CLng("&H" & HEXStr)
Конечная функция
Код работает нормально, в нем нет ничего плохого, но мы можем написать более «продвинутый» код, используя оператор LSet:
Скопируйте код кода следующим образом:
Частный тип myBytes
B1 как байт
B2 как байт
B3 как байт
B4 как байт
Тип окончания
Частный тип myLong
Вэл как долго
Тип окончания
'Демоном
'http://VeVB.COM
Открытая функция IP2Long (ip As String) до тех пор, пока
Dim a() как строка
Dim b As myBytes
Дим л как мойдлинный
а = Разделить(ip, ".")
'Обратите внимание на Little-Endian
b.B1 = CByte(a(3))
b.B2 = CByte(a(2))
b.B3 = CByte(a(1))
b.B4 = CByte(a(0))
LSet l = b
IP2Long = l.Val
Конечная функция
Используйте LSet для копирования переменной типа myBytes в переменную типа myLong. Это очень хорошо и мощно. Взгляните на сгенерированный ассемблерный код:
Скопируйте код кода следующим образом:
00401A0E lea eax, dword ptr [ebp-0x20] адрес переменной b;
00401A11 нажимной eax
00401A12 lea eax, dword ptr [ebp-0x14] адрес переменной l;
00401A15 нажимной eax
00401A16 нажмите 0x4
00401A18 вызов __vbaCopyBytes ; jmp в MSVBVM60.__vbaCopyBytes;
В MSVBVM60.DLL это называется __vbaCopyBytes. Первый параметр — это копируемый байт, второй параметр — целевой адрес, а третий параметр — исходный адрес. Он аналогичен функции memcpy в стандартной библиотеке C. за исключением того, что порядок параметров другой, а его внутренняя реализация — не что иное, как инструкции по передаче строк в ассемблере:
Скопируйте код кода следующим образом:
72A1A0F3 > mov ecx, двойное слово ptr [esp+0x4]
72A1A0F7 нажмите esi
72A1A0F8 mov esi, dword ptr [esp+0x10]
72A1A0FC нажмите редактирование
72A1A0FD mov edi, dword ptr [esp+0x10]
72A1A101 перемещение eax,ecx
72A1A103 мов edx, edi
72A1A105 шреккс, 0x2
72A1A108 Rep movs dword ptr es:[edi], dword ptr [esi]
72A1A10A перемещение ecx, eax
72A1A10C перемещение eax, edx
72A1A10E и ecx, 0x3
72A1A111 Rep movs byte ptr es:[edi], byte ptr [esi]
72А1А113 попеди
72A1A114 поп еси
72A1A115 возврат 0xC
Следует отметить, что документация нас предупреждает:
Скопируйте код кода следующим образом:
Предупреждение. Использование LSet для копирования переменной одного определяемого пользователем типа в переменную другого определяемого пользователем типа не рекомендуется. Копирование данных одного типа в пространство, зарезервированное для другого типа данных, может привести к непредсказуемым результатам.
Когда вы копируете переменную из одного определяемого пользователем типа в другой, двоичные данные из одной переменной копируются в пространство памяти другой, независимо от типов данных, указанных для элементов.
Использование LSet для копирования переменных пользовательского типа не рекомендуется и может привести к неожиданным результатам (например, к смещению структур), поэтому не используйте оператор LSet, если вы не знаете, что делаете.