Runtime Building: Không tìm thấy chuỗi trong phạm vi này
Một vấn đề phổ biến mà các nhà phát triển chất nền có thể gặp phải: phát triển một pallet tùy chỉnh để lưu trữ ánh xạ vào kho lưu trữ với các loại phổ biến, chẳng hạn như String. Ví dụ:
#[derive(Encode, Decode, Clone, Default, RuntimeDebug)]
pub struct ClusterMetadata {
ip_address: String,
namespace: String,
whitelisted_ips: String,
}
Khi xây dựng thời gian chạy, bạn gặp lỗi này cho mỗi String:
|
21 | ip_address: String,
| ^^^^^^ not found in this scope
Tại sao Stringskhông được bao gồm trong phạm vi? Và các stdloại rỉ sét khác?
Trả lời
Lỗi ở đây không liên quan đến no_std, vì vậy bạn có thể chỉ cần nhập Stringloại để nhận được lỗi thực sự với việc sử dụng chuỗi trong thời gian chạy.
Vấn đề thực sự mà bạn sẽ thấy là nó Stringkhông thể được mã hóa bởi Parity SCALE Codec, đây rõ ràng là một yêu cầu đối với bất kỳ mục lưu trữ nào (hoặc hầu hết bất kỳ loại nào bạn muốn sử dụng) trong thời gian chạy.
Vậy câu hỏi đặt ra là "Tại sao SCALE không mã hóa String"?
Đây là do sự lựa chọn. Nói chung, Stringlà loại phức tạp đáng ngạc nhiên. Cuốn sách Rust dành cả một phần để nói về sự phức tạp của loại hình này.
Do đó, nó có thể dễ dàng trở thành một chân ngắn trong môi trường thời gian chạy mà mọi người sử dụng Stringkhông đúng cách.
Hơn nữa, việc lưu trữ Strings trong bộ lưu trữ thời gian chạy là một thực tiễn không tốt . Tôi nghĩ rằng chúng ta có thể dễ dàng đồng ý rằng giảm thiểu việc sử dụng bộ nhớ trong thời gian chạy là cách tốt nhất và do đó bạn chỉ nên đưa vào các mục lưu trữ mà bạn cần để có thể tạo ra sự đồng thuận và chuyển đổi trạng thái trong thời gian chạy của mình. Thông thường, Stringdữ liệu sẽ được sử dụng cho siêu dữ liệu và kiểu sử dụng này không phải là phương pháp hay nhất.
Nếu bạn xem xét kỹ hơn Substrate, bạn sẽ thấy rằng chúng tôi vi phạm phương pháp hay nhất này nhiều lần, nhưng đây là quyết định mà chúng tôi đưa ra một cách rõ ràng, có đầy đủ thông tin để có thể đánh giá chính xác chi phí / lợi ích.
Tất cả những điều này kết hợp lại là lý do tại sao Strings không được coi là một đối tượng lớp đầu tiên trong thời gian chạy. Thay vào đó, chúng tôi yêu cầu người dùng mã hóa chuỗi thành từng byte, sau đó làm việc với mảng byte đó.