Construcción en tiempo de ejecución: cadena no encontrada en este ámbito

Dec 18 2020

Un problema común con el que se pueden encontrar los desarrolladores de sustrato: desarrollar una paleta personalizada para almacenar el mapeo en el almacenamiento con tipos comunes, como String. Como ejemplo:

#[derive(Encode, Decode, Clone, Default, RuntimeDebug)]
pub struct ClusterMetadata {
    ip_address: String,
    namespace: String,
    whitelisted_ips: String,
}

Al construir el tiempo de ejecución, obtienes este error para cada String:

     |
  21 |     ip_address: String,
     |                 ^^^^^^ not found in this scope

¿Por qué Stringsno están incluidos en el alcance? ¿Y otros stdtipos de óxido?

Respuestas

4 ShawnTabrizi Dec 18 2020 at 07:35

El error aquí no está relacionado con no_std, por lo que probablemente solo necesite importar el Stringtipo para obtener los errores reales con el uso de cadenas en el tiempo de ejecución.

El problema real que encontrará es que Stringno es codificable por Parity SCALE Codec, que obviamente es un requisito para cualquier elemento de almacenamiento (o la mayoría de los tipos que desee utilizar) en el tiempo de ejecución.

Entonces, la pregunta es "¿Por qué SCALE no codifica String"?

Esto es por elección. En general, Stringes de tipo sorprendentemente complejo. El libro de Rust dedica toda una sección a hablar de las complejidades del tipo.

Como tal, puede convertirse fácilmente en una pistola dentro del entorno de tiempo de ejecución que la gente usa Stringincorrectamente.

Además, generalmente es una mala práctica almacenar Stringcorreos electrónicos en el almacenamiento en tiempo de ejecución. Creo que podemos estar fácilmente de acuerdo en que minimizar el uso del almacenamiento en el tiempo de ejecución es una práctica recomendada y, por lo tanto, solo debe colocar en el almacenamiento los elementos que necesita para poder derivar consenso y transiciones de estado en su tiempo de ejecución. La mayoría de las veces, los Stringdatos se utilizarían para metadatos, y este tipo de uso no es la mejor práctica.

Si observa más de cerca el Sustrato, encontrará que rompemos esta mejor práctica más de una vez, pero esta es una decisión que tomamos explícitamente, teniendo la información a mano para poder evaluar correctamente el costo / beneficio.

Todo esto combinado es la razón por la que los Strings no se tratan como un objeto de primera clase en el tiempo de ejecución. En cambio, pedimos a los usuarios que codifiquen cadenas en bytes y luego trabajen con esa matriz de bytes.