Три разных способа создания экземпляров массивов в AssemblyScript
Я пишу смарт-контракт и хочу использовать массивы для управления данными, но, глядя на документы AssemblyScript, я не уверен, что лучше всего продолжить.
Мне кажется нормальным просто использовать:
let testData:string[] = []
но когда я проконсультировался с документами по сценариям сборки, есть три рекомендуемых способа создания массива:
// The Array constructor implicitly sets `.length = 10`, leading to an array of
// ten times `null` not matching the value type `string`. So, this will error:
var arr = new Array<string>(10);
// arr.length == 10 -> ERROR
// To account for this, the .create method has been introduced that initializes
// the backing capacity normally but leaves `.length = 0`. So, this will work:
var arr = Array.create<string>(10);
// arr.length == 0 -> OK
// When pushing to the latter array or subsequently inserting elements into it,
// .length will automatically grow just like one would expect, with the backing
// buffer already properly sized (no resize will occur). So, this is fine:
for (let i = 0; i < 10; ++i) arr[i] = "notnull";
// arr.length == 10 -> OK
Когда я захочу использовать один тип создания экземпляра поверх другого? Почему бы мне просто всегда не использовать ту версию, которую я представил в начале?
2 ответа
Нет ничего плохого в подходе, основанном на буквальном массиве. Это в основном эквивалентно
let testData = new Array<string>();
Однако иногда вы знаете, какой должна быть длина массива, и в таких случаях предварительно выделяйте память с помощью Array.create
более эффективен.
ОБНОВИТЬ
С этим PR Array.create
устарело и больше не должно использоваться.
СТАРЫЙ ОТВЕТ
let testData:string[] = []
семантически то же, что и
let testData = new Array<string>()
AssemblyScript не поддерживает предварительно выделенные разреженные массивы (массивы с отверстиями) для ссылочных элементов, которые явно не объявлены как допускающие значение NULL, например:
let data = new Array<string>(10);
data[9] = 1; // will be compile error
Вместо этого вы можете использовать:
let data = new Array<string | null>(10);
assert(data.length == 10); // ok
assert(data[0] === null); // ok
или Array.create
но в этом случае ваша длина будет равна нулю. Array.create
на самом деле просто резервная емкость для резервного буфера.
let data = Array.create<string>(10);
assert(data.length == 0); // true
Для простых (не ссылочных) типов вы можете использовать обычный способ, не заботясь о nullabe или создании массива через Array.create
:
let data = new Array<i32>(10);
assert(data.length == 10); // ok
assert(data[0] == 0); // ok