¿Inicializar matrices y estructuras vacías en estructuras gráficas de almacenamiento basadas en estructuras?

¿Cómo inicializo matrices y estructuras vacías en estructuras de datos de estructuras anidadas?

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);
        }

Respuestas (1)

De la documentación de Solidity sobre matrices dinámicas :

Las matrices tienen un miembro de longitud que contiene su número de elementos. La longitud de las matrices de memoria es fija (pero dinámica, es decir, puede depender de los parámetros de tiempo de ejecución) una vez que se crean. Para arreglos de tamaño dinámico (solo disponible para almacenamiento), este miembro se puede asignar para cambiar el tamaño del arreglo.

y sobre la falta de valores nulos :

El concepto de valores "indefinidos" o "nulos" no existe en Solidity, pero las variables recién declaradas siempre tienen un valor predeterminado que depende de su tipo. Para manejar valores inesperados, debe usar la función de reversión para revertir toda la transacción o devolver una tupla con un segundo valor booleano que indique el éxito.

En su ejemplo, en lugar de crear la nueva estructura en la memoria y luego usarla pushpara agregarla a la matriz de almacenamiento, puede aumentar la longitud que books[_bookID].chaptersinicializará una nueva ChapterDataestructura vacía. Luego edite esta nueva estructura de almacenamiento en su lugar.

    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;

    }
Entiendo que estos tipos se inicializarán con un valor 0, pero no puede simplemente ignorar los elementos de una estructura, deben declararse estrictamente e inicializarse con un valor cuando intente agregar una estructura a otra estructura.
lo siento, entendí un poco mal la pregunta. He editado mi respuesta, espero que sea más útil.