Runtime Building: ไม่พบสตริงในขอบเขตนี้

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ชนิดเพื่อรับข้อผิดพลาดจริงโดยใช้สตริงในรันไทม์

ปัญหาที่แท้จริงที่คุณจะพบคือStringParity SCALE Codec ไม่สามารถเข้ารหัสได้ซึ่งเห็นได้ชัดว่าเป็นข้อกำหนดสำหรับรายการจัดเก็บข้อมูลใด ๆ (หรือเกือบทุกประเภทที่คุณต้องการใช้) ในรันไทม์

คำถามคือ "ทำไม SCALE ไม่เข้ารหัสString"?

นี่คือทางเลือก โดยทั่วไปStringเป็นประเภทที่ซับซ้อนอย่างน่าประหลาดใจ หนังสือ Rust ใช้เวลาทั้งส่วนเพื่อพูดคุยเกี่ยวกับความซับซ้อนของประเภท

ด้วยเหตุนี้มันอาจกลายเป็นปืนพกภายในสภาพแวดล้อมรันไทม์ที่ผู้คนใช้Stringอย่างไม่ถูกต้อง

นอกจากนี้โดยทั่วไปแล้วการจัดเก็บStringในหน่วยเก็บข้อมูลรันไทม์ถือเป็นแนวทางปฏิบัติที่ไม่ดี ฉันคิดว่าเราสามารถยอมรับได้อย่างง่ายดายว่าการลดการใช้พื้นที่เก็บข้อมูลในรันไทม์เป็นแนวทางปฏิบัติที่ดีที่สุดดังนั้นคุณควรใส่เฉพาะรายการจัดเก็บข้อมูลที่คุณต้องการเพื่อให้ได้มาซึ่งฉันทามติและการเปลี่ยนสถานะในรันไทม์ของคุณ โดยส่วนใหญ่Stringข้อมูลจะถูกใช้สำหรับข้อมูลเมตาและการใช้งานประเภทนี้ไม่ใช่แนวทางปฏิบัติที่ดีที่สุด

หากคุณพิจารณาอย่างละเอียดมากขึ้นที่ Substrate คุณจะพบว่าเราฝ่าฝืนแนวทางปฏิบัติที่ดีที่สุดนี้มากกว่าหนึ่งครั้ง แต่นี่เป็นการตัดสินใจที่เราทำอย่างชัดเจนโดยมีข้อมูลอยู่ในมือเพื่อให้สามารถประเมินต้นทุน / ผลประโยชน์ได้อย่างถูกต้อง

ทั้งหมดนี้รวมกันเป็นเหตุให้Strings ไม่ถือว่าเป็นวัตถุชั้นหนึ่งในรันไทม์ แต่เราขอให้ผู้ใช้เข้ารหัสสตริงเป็นไบต์จากนั้นทำงานกับอาร์เรย์ไบต์นั้นแทน