Одна из самых странных причуд языка программирования Solidity — отсутствие null. Придя из Swift, где возможность null является одним из основных строительных блоков, я почувствовал себя чужим. Сначала я не понимал, как можно писать код без такой полезной функции. В этой статье мы расскажем о том, как обойти эту проблему в Solidity при создании смарт-контрактов.
Понятие неопределенного
Концепция undefined
, null
, nil
, None
и т. д. существует в таких языках, как JavaScript, Java, Python, Swift, .etc., но ее нет в Solidity.
В Solidity мы можем назвать это нулевым значением или значением по умолчанию. Это связано с тем, что каждое значение после создания получает слот в памяти и должно что-то содержать.
Значения по умолчанию
Чтобы поговорить о значениях по умолчанию, мы должны разделить типы Solidity на два блока:
- динамически изменяемые типы, такие как
string
,bytes
, и массивы; - нединамические типы, такие как
int
,bool
иaddress
.
Типы нединамического размера
С типами нединамического размера игра довольно проста. Вот значения по умолчанию для них:
- для
bool
этоfalse
;
Если мы хотим создать struct
, то значением по умолчанию будет кортеж из всех значений по умолчанию его членов.
Для enum
значение по умолчанию — это первый случай. Это может быть очень странный подход, но это потому, что все случаи enum
за кадром представляют собой массив целых чисел uint8
.
Динамически изменяемые типы
С динамически изменяемыми типами дело обстоит иначе:
- значением по умолчанию для
string
является пустаяstring
; - Значение по умолчанию для массива — пустой массив;
Код вдоль
Чтобы проиллюстрировать значения по умолчанию в коде, давайте создадим Employee struct
с enum
EmployeeType
.
enum EmployeeType {
Employee,
Contractor,
PartTime
}
struct Person {
EmployeeType employeeType;
bool deleted;
string name;
uint256 yearOfBirth;
address walletAddress;
uint256[] doorAccess;
}
Теперь мы можем инициализировать новый экземпляр Employee
struct
. Помните, что нам не нужно предоставлять значения членов, а только распределить их в памяти.
Person person;
Если мы выведем значение person
, то получим кортеж значений по умолчанию для каждого члена Person
struct
.
tuple(uint8,bool,string,uint256,address,uint256[]): 0,false,,0,0x0000000000000000000000000000000000000000,
Проверка нулевого значения
Теперь, когда мы знаем значения по умолчанию, мы можем проверить, является ли что-то «нулевым» или, точнее говоря, имеет ли оно значение по умолчанию.
function check() external view {
console.log(person.deleted == false);
console.log(bytes(person.name).length == 0);
console.log(person.yearOfBirth == 0);
console.log(person.walletAddress == address(0));
console.log(person.employeeType == EmployeeType.Employee);
console.log(person.doorAccess.length == 0);
}
Выполнив эту функцию, мы получим true
для всех проверок. Таким образом, мы можем понять, что значение не определено.
Deleted true
Name true
Year of birth true
Wallet address true
Employee type true
Door access true
Стоит отметить, что для типа ‘string’ мы преобразовали его в bytes
и проверили его длину. Есть и другой способ добиться этого, но об этом мы поговорим в одном из будущих постов.
TL;DR
В языке программирования Solidity нет функции nullability, которая распространена во многих языках, таких как Swift и JavaScript. Вместо этого типы имеют значения по умолчанию, например, ноль 0
для uint
. Очень важно знать значения по умолчанию, потому что это пригодится, когда мы захотим проверить, определено ли что-то или нет.
Ссылки
-
Код примера
-
Официальная документация — Типы
-
Область видимости и объявления
-
Обсуждение на StackOverflow