ランタイム構築:このスコープに文字列が見つかりません

Dec 18 2020

基板開発者が遭遇する可能性のある一般的な問題:マッピングをなどの一般的なタイプのストレージに格納するカスタムパレットの開発String。例として:

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

ランタイムを構築すると、次のすべてに対してこのエラーが発生しますString

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

なぜStringsスコープに含まれないのですか?そして他のstd錆の種類?

回答

4 ShawnTabrizi Dec 18 2020 at 07:35

ここでのエラーはに関連していないno_stdためString、実行時に文字列を使用して実際のエラーを取得するには、おそらく型をインポートする必要があります。

あなたが見つける本当の問題は、Stringパリティスケールコーデックによってエンコードできないことです。これは明らかに、ランタイムのストレージアイテム(または使用したいほとんどのタイプ)の要件です。

それで、質問は「なぜSCALEはエンコードしないのStringですか?」です。

これは選択によるものです。一般的に、String驚くほど複雑なタイプです。Rustの本は、このタイプの複雑さについて話しているセクション全体を費やしています。

そのため、ランタイム環境内で、人々がString誤って使用するフットガンになる可能性があります。

さらに、Stringをランタイムストレージに保存することは一般的に悪い習慣です。ランタイムでのストレージ使用量を最小限に抑えることがベストプラクティスであることに簡単に同意できると思います。したがって、ランタイムでコンセンサスと状態遷移を導き出すことができる必要があるストレージアイテムのみを配置する必要があります。ほとんどの場合、Stringデータはメタデータに使用されますが、この種の使用法はベストプラクティスではありません。

Substrateを詳しく見ると、このベストプラクティスに何度も違反していることがわかりますが、これは明示的に行う決定であり、コスト/メリットを正しく評価できるように手元に情報があります。

これらすべてが組み合わされて、Stringsがランタイムでファーストクラスオブジェクトとして扱われない理由です。代わりに、文字列をバイトにエンコードしてから、代わりにそのバイト配列を操作するようにユーザーに依頼します。