Runtime Building: ไม่พบสตริงในขอบเขตนี้
ปัญหาทั่วไปที่นักพัฒนาวัสดุพิมพ์อาจพบ: การพัฒนาพาเลทแบบกำหนดเองเพื่อจัดเก็บการแมปลงในหน่วยเก็บข้อมูลด้วยประเภททั่วไปเช่น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สนิมชนิดอื่น ๆ?
คำตอบ
ข้อผิดพลาดที่นี่ไม่เกี่ยวข้องกับno_stdดังนั้นคุณอาจต้องนำเข้าStringชนิดเพื่อรับข้อผิดพลาดจริงโดยใช้สตริงในรันไทม์
ปัญหาที่แท้จริงที่คุณจะพบคือStringParity SCALE Codec ไม่สามารถเข้ารหัสได้ซึ่งเห็นได้ชัดว่าเป็นข้อกำหนดสำหรับรายการจัดเก็บข้อมูลใด ๆ (หรือเกือบทุกประเภทที่คุณต้องการใช้) ในรันไทม์
คำถามคือ "ทำไม SCALE ไม่เข้ารหัสString"?
นี่คือทางเลือก โดยทั่วไปStringเป็นประเภทที่ซับซ้อนอย่างน่าประหลาดใจ หนังสือ Rust ใช้เวลาทั้งส่วนเพื่อพูดคุยเกี่ยวกับความซับซ้อนของประเภท
ด้วยเหตุนี้มันอาจกลายเป็นปืนพกภายในสภาพแวดล้อมรันไทม์ที่ผู้คนใช้Stringอย่างไม่ถูกต้อง
นอกจากนี้โดยทั่วไปแล้วการจัดเก็บStringในหน่วยเก็บข้อมูลรันไทม์ถือเป็นแนวทางปฏิบัติที่ไม่ดี ฉันคิดว่าเราสามารถยอมรับได้อย่างง่ายดายว่าการลดการใช้พื้นที่เก็บข้อมูลในรันไทม์เป็นแนวทางปฏิบัติที่ดีที่สุดดังนั้นคุณควรใส่เฉพาะรายการจัดเก็บข้อมูลที่คุณต้องการเพื่อให้ได้มาซึ่งฉันทามติและการเปลี่ยนสถานะในรันไทม์ของคุณ โดยส่วนใหญ่Stringข้อมูลจะถูกใช้สำหรับข้อมูลเมตาและการใช้งานประเภทนี้ไม่ใช่แนวทางปฏิบัติที่ดีที่สุด
หากคุณพิจารณาอย่างละเอียดมากขึ้นที่ Substrate คุณจะพบว่าเราฝ่าฝืนแนวทางปฏิบัติที่ดีที่สุดนี้มากกว่าหนึ่งครั้ง แต่นี่เป็นการตัดสินใจที่เราทำอย่างชัดเจนโดยมีข้อมูลอยู่ในมือเพื่อให้สามารถประเมินต้นทุน / ผลประโยชน์ได้อย่างถูกต้อง
ทั้งหมดนี้รวมกันเป็นเหตุให้Strings ไม่ถือว่าเป็นวัตถุชั้นหนึ่งในรันไทม์ แต่เราขอให้ผู้ใช้เข้ารหัสสตริงเป็นไบต์จากนั้นทำงานกับอาร์เรย์ไบต์นั้นแทน