Construcción en tiempo de ejecución: cadena no encontrada en este ámbito
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é Strings
no están incluidos en el alcance? ¿Y otros std
tipos de óxido?
Respuestas
El error aquí no está relacionado con no_std
, por lo que probablemente solo necesite importar el String
tipo para obtener los errores reales con el uso de cadenas en el tiempo de ejecución.
El problema real que encontrará es que String
no 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, String
es 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 String
incorrectamente.
Además, generalmente es una mala práctica almacenar String
correos 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 String
datos 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 String
s 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.