¿Cuál es el valor cero, vacío o nulo de una estructura?

Si tengo una asignación de cadena => estructura definida personalizada, ¿cómo verifico si un valor está definido en la asignación?

Los documentos establecen que "todas las claves posibles existen y se asignan a un valor cuya representación de bytes es todo ceros".

¿Cuál es el valor cero de una estructura definida de forma personalizada de modo que uno pueda verificar condicionalmente su existencia?

Sí, de hecho. Gracias ¿Debería eliminar el tema?
No, solo se deben eliminar las preguntas fuera de tema o ininteligibles. Los duplicados son bastante útiles para mantenerlos, ya que hay varias formas de formular una pregunta.

Respuestas (4)

Verifica que un valor esté definido en el mapeo verificando que no sea cero.

Si una configuración explícita de cero tiene significado para su aplicación, necesita datos auxiliares (o estructura) para rastrear cuándo se ha establecido explícitamente un valor de cero.

Un enfoque ligero sería agregar una boolpropiedad a la estructura (por ejemplo, named initialized) y configurarla truecuando el cero se establece explícitamente. Como todos los valores booleanos son falsos (0) de forma predeterminada, puede comprobar el valor true.

Como alternativa, verifique que cada miembro de la estructura sea cero. Si un miembro es un string, conviértalo en bytesy luego verifique que su longitud sea cero .

Para ver un ejemplo , consulte Cómo probar si una variable de estado de estructura está configurada

Es posible que se necesite otra estructura de datos o mapeo según la aplicación.


Aquí hay un ejemplo relacionado sobre el uso de un par para verificar el significado de cero :

contract C {
    uint[] counters;
    function getCounter(uint index)
        returns (uint counter, bool error) {
            if (index >= counters.length) return (0, true);
            else return (counters[index], false);
        }
    function checkCounter(uint index) {
        var (counter, error) = getCounter(index);
        if (error) { ... }
        else { ... }
    }
}
Para aclarar (porque esto difiere de los otros idiomas en los que trabajo), puedo verificar structMapping[key].initalized == false incluso cuando esa clave no se ha definido en el mapeo.
Sí, el valor predeterminado para todo en la máquina virtual Ethereum (en la que se basa Solidity) es cero. (Cualquier cosa no inicializada es cero, a diferencia de otros idiomas donde los valores pueden ser "basura").
¿Sería posible usar una cadena en lugar de un bool? (diciendo: tengo una enumeración para la que solo tengo propiedades de cadena) Entonces: ¿con qué debe comparar la estructura de cadena? (en otras palabras: cuál es el valor predeterminado para una cadena)
Ser capaz de probar el valor de los miembros arbitrarios antes de saber si la estructura está inicializada también significa que es posible que ni siquiera necesite saber la respuesta a esa pregunta en primer lugar: puede asignar miembros de inmediato. Lo sé, ya estoy sintiendo la bofetada del segfault en mi cara también, pero Solidity es su propia bestia.

Realmente no existe tal cosa como "vacío". Un índice no inicializado de la asignación es simplemente igual al valor "cero" del tipo adecuado.

Para verificar si se ha asignado un valor, simplemente verifique si balances[msg.sender]== 0. Si un usuario accede al contrato, pero el saldo debe ser 0, puede usar una dirección => mapeo int256 y usar -1 para 0 saldos

function checkArray(bytes a) returns (bool){
    if ((a) && (a.length > 0))
        return true;
    return false;
}
Dame un error: Operator && not compatible with types bytes memory and boolsolidez 0.4.7

Para un valor de índice sin firmar de una matriz de estructuras (por ejemplo, Cliente), para verificar si la entrada existe en una matriz de estructuras dada, puede hacer algo como lo siguiente:

 struct Customer {
    string userName;
    string dataHash;
    address bank;
    int256 upVotes;
}

Customer[] public customers; 

...
//assuming we have some customers added (customers.length>0)
...

function getCustomerIndex(string memory userName) internal view returns(bool, uint256) {
    for(uint i=0; i<customers.length; i++) {
        if (stringEquals(customers[i].userName, userName)){
            return (true, i);
        }
    }
    return (false, 0);
}

El explícito (falso, 0) sugiere que el cliente con el nombre de usuario dado no se encuentra en la matriz de estructura de clientes.

Ahora, en mi otro código, puedo usar la función anterior de la siguiente manera:

// return 1 implies customer found and removed from struct Customer array
// return 0 implies no customer found in the struct Customer array
function removeCustomer(string calldata userName) external returns (uint8) {
        (bool result, uint256 index) = getCustomerIndex(userName);
        if (result){
            for (uint i=index+1; i<customers.length-1; i++){
                customers[i-1] = customers[i];
            }
            customers.length--;
            return 1;
        }
        return 0;
    }