Solidez: se puede ignorar el mapeo inicial de la estructura

Descubrí que, en la inicialización de la estructura, podemos simplemente ignorar el tipo de mapeo, por ejemplo:

pragma solidity ^0.4.0;

contract C{
  struct Person{
    string name;
    mapping(address=>int) map;
    string[] nickNames;
    int age;
  }

  function init() constant returns (string, int){
    string[] memory nickNames = new string[](1);
    nickNames[0] = "cat1099";

    Person memory p = Person("Jack", nickNames, 23);

    return (p.name, p.age);
  }
}

En el documento de la oficina , solo encontré en una nota de código, dice "Omitimos el tipo de mapeo". Después de buscar en este sitio, aquí alguien dijo que:

Las asignaciones se pueden ver como tablas hash que se inicializan virtualmente de modo que existen todas las claves posibles y se asignan a un valor cuya representación de bytes es todo ceros: el valor predeterminado de un tipo. Sin embargo, la similitud termina aquí: los datos clave en realidad no se almacenan en un mapeo, solo se usa su hash keccak256 para buscar el valor.

¿Significa esto que solidty no puede inicializar una estructura de mapeo, así que simplemente ignóralo? ¿Alguien podría dejarlo más claro, ya que no hay ninguna explicación oficial de esto?

Respuestas (1)

Como desarrollador, puede considerar la asignación como todos los pares clave/valor posibles, con los valores inicializados en 0, falso, matriz vacía, etc. según el tipo. No es necesario inicializar explícitamente. simplemente son

Esto incluye mapeos dentro de estructuras. Los valores permanecerán en cero hasta que se establezcan explícitamente.

Las asignaciones dentro de estructuras pueden ser útiles, así como las asignaciones de estructuras, o ambas, como se muestra a continuación.

Las claves no se almacenan en asignaciones.

Considerarmapping(uint => address) numberedAddresses;

La clave ( uint) se codifica para encontrar una "ranura" y addressse almacena un correo electrónico en esa ranura. La clave en sí no se almacena. La única manera de recuperar un valor mapeado es devolverlo usando el conocimiento de la clave:

numberedAddress[key];

Hay algunas implicaciones con las que familiarizarse. No es posible enumerar las claves en una asignación. Del mismo modo, no es posible contarlos. Podríamos decir "todas las claves posibles existen" en todos los casos.

Si uno quiere enumerar las claves que realmente configuramos (comunes), entonces debe almacenar las claves en otro lugar. Hay algunos patrones de ejemplo aquí, por ejemplo, Mapped Structs with Index, para ayudar a prevenir la reinvención de cosas. ¿Existen patrones de almacenamiento sencillos y bien resueltos para Solidity? .

El siguiente ejemplo está destinado a jugar en Remix. Obtendrá los 0 resultados para cualquier clave de los captadores hasta que establezca algo explícitamente. Las últimas dos funciones muestran cómo trabajar con un mapeo que está almacenado dentro de una estructura.

Espero eso ayude.

pragma solidity ^0.4.6;

contract Mappings {

    // For all new structs, all answer flags at all key locations are false until set. 

    struct UserStruct {
        uint balanceOf;
        bool isActive;
        mapping(uint => bool) answerFlags;
    }

    // Key => Struct. All keys initialize to 0.
    // Query any unset Key and get balanceOf == 0 and isActive == false.

    // (More common to use address => struct for "users") 

    mapping(uint => UserStruct) public userStructs;

    // Key => Bool. All keys initialize to false
    // Query any unset key and get false.

    mapping(uint => bool) public addressFlags;

    // Set values in storage

    function setUserStruct(uint key, uint balanceOf, bool isActive) public returns(bool success) {
        userStructs[key].balanceOf = balanceOf;
        userStructs[key].isActive  = isActive;
        return true;
    }

    function setAddressFlag(uint key, bool flagAddress) public returns(bool success) {
        addressFlags[key] = flagAddress;
        return true;
    }

    // Mapping inside a struct

    function getUserAnswerFlag(uint userStructKey, uint userAnswerKey) public constant returns(bool answerFlag) {
        return userStructs[userStructKey].answerFlags[userAnswerKey];
    }

    function setUserAnswerFlag(uint userStructKey, uint userAnswerKey, bool setValue) public returns(bool success) {
        userStructs[userStructKey].answerFlags[userAnswerKey] = setValue;
        return true;
    }

}