Инициализация пустых массивов и структур в графических структурах хранения на основе структур?

Как инициализировать пустые массивы и структуры во вложенных структурах данных?

contract NewBook {

        struct ReviewerData {
            string name,
            uint industryXP
            // foobar...
        }

        struct ChapterData {
            // string chapterID;
            string title;
            string color;
            uint pages;
            //How do I initialise the two elements below with empty values?
            ReviewerData[] reviewer;
            address[] reviewers;
        }

        struct BookData {
            // string bookID;
            ChapterData[] chapters;
        }

        mapping(bytes32 => BookData) books; // bookId => BookData

        function addChapter(bytes32 _bookID, string memory title, string color, uint pages) public {
            ChapterData memory c = ChapterData({
                title: title,
                color: color,
                pages: pages,
                //how to initialise empty reviewer struct?
                //how to initialise empty reviewers array?
            });
            books[_bookID].chapters.push(c);
        }

Ответы (1)

Из документации Solidity по динамическим массивам :

Массивы имеют член длины, который содержит их количество элементов. Длина массивов памяти является фиксированной (но динамической, т.е. может зависеть от параметров времени выполнения) после их создания. Для массивов с динамическим размером (доступных только для хранения) этот член может быть назначен для изменения размера массива.

и об отсутствии нулевых значений :

В Solidity не существует концепции «неопределенных» или «нулевых» значений, но вновь объявленные переменные всегда имеют значение по умолчанию, зависящее от их типа. Чтобы обработать любые непредвиденные значения, вы должны использовать функцию revert, чтобы отменить всю транзакцию, или вернуть кортеж со вторым логическим значением, обозначающим успех.

В вашем примере вместо того, чтобы создавать новую структуру в памяти, а затем использовать pushее для добавления в массив хранения, вы можете увеличить длину, которая books[_bookID].chaptersбудет инициализировать новую пустую ChapterDataструктуру. Затем отредактируйте эту новую структуру хранения на месте.

    function addChapter(bytes32 _bookID, string memory title, string color, uint pages) public {
        uint _length = books[_bookID].chapters.length;
        books[_bookID].chapters.length++;

        ChapterData storage c = books[_bookID].chapters[_length];
        c.title = title;
        c.color = color;
        c.pages = pages;

    }
Я понимаю, что эти типы будут инициализированы значением 0, но вы не можете просто игнорировать элементы структуры, они должны быть строго объявлены и инициализированы значением, когда вы пытаетесь добавить структуру в другую структуру.
извините, я немного неправильно понял вопрос. Я отредактировал свой ответ, надеюсь, он будет более полезным.