WASM - это виртуальная машина низкого уровня, поэтому она должна иметь возможность обрабатывать строки, представленные в виде двоичных массивов.
Есть удобные методы .fromUTF8 и .toUTF8: https://github.com/AssemblyScript/assemblyscript/blob/master/std/assembly/string.ts#L499
Однако они несимметричны по трем причинам:
fromUTF8
требует знания длины строки, а toUTF8
не возвращает это значение. Вы должны вызвать lengthUTF8
отдельно, что является расточительным (он уже вызван в toUTF8
)fromUTF8
правильно обрабатывает символы Юникода \0
в строках, в то время как toUTF8
создает впечатление, что они не поддерживаютсяfromUTF8
требует чистого размера закодированной строки в байтах, а lengthUTF8
возвращает размер с нулевым заполнением байтов. Даже существующие тесты должны явно настраиваться на это: https://github.com/AssemblyScript/assemblyscript/blob/b7e7be20cfe2d35c689d7927ee0e4207a443bb6f/tests/compiler/std/string-utf8.ts#L24Это неэффективный и запутанный подход. Если целью AssemblyScript является создание высокоуровневого WASM-дружественного языка, то наличие C-измов в стандартной библиотеке, таких как голые указатели на строки с завершающим нулем, похоже, идет вразрез с этими целями.
Я предлагаю переименовать .lengthUTF8 и .toUTF8 в .lengthUTF8ZeroTerminated, .toUTF8ZeroTerminated и ввести .toUTF8Buffer, который возвращает ArrayBuffer, заполненный правильным содержимым и размером. Этот API будет намного понятнее и удобнее для пользователей.
Альтернативным решением было бы ввести базовый тип, например
class MemSlice {
constructor(readonly offset: usize, readonly length: usize) {}
...
}
что будет весьма полезно в целом
Согласитесь, эти API не идеальны. Возможно, даже имеет смысл переместить их из строкового класса во что-то специально предназначенное для взаимодействия (с C).
UTF8 / UTF16 api был улучшен в этом PR
Самый полезный комментарий
Альтернативным решением было бы ввести базовый тип, например
что будет весьма полезно в целом