运行时构建:在此范围内找不到字符串

Runtime Building: String not found in this scope

基板开发人员可能 运行 遇到的一个常见问题:开发自定义托盘以将映射存储到具有常见类型的存储器中,例如 String。例如:

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

构建 运行time 时,每个 String:

都会出现此错误
     |
  21 |     ip_address: String,
     |                 ^^^^^^ not found in this scope

为什么 Strings 没有包含在范围内?还有其他 std 锈蚀类型?

此处的错误与 no_std 无关,因此您可能只需要导入 String 类型以获取在运行时使用字符串的真正错误。

您会发现真正的问题是 String 不能被 Parity SCALE 编解码器编码,这显然是运行时对任何存储项(或您想要使用的大多数类型)的要求。

所以问题是“为什么 SCALE 不编码 String”?

这是自愿的。通常,String 是一种非常复杂的类型。 Rust 书花了 a whole section 谈论类型的复杂性。

因此,它很容易成为人们错误使用 Strings 的运行时环境中的脚枪。

此外,将 String 存储在运行时存储中通常是不好的做法。我认为我们可以很容易地同意最小化运行时的存储使用是最佳实践,因此您应该只将需要能够在运行时获得共识和状态转换的存储项放入。大多数情况下,String 数据将用于元数据,这种用法不是最佳做法。

如果你更仔细地观察 Substrate,你会发现我们不止一次打破了这个最佳实践,但这是我们明确做出的决定,掌握了手头的信息才能正确评估 cost/benefit.

所有这些结合在一起就是为什么 Strings 在运行时不被视为第一个 class 对象。相反,我们要求用户将字符串编码为字节,然后使用该字节数组。