【问题标题】:How can I implement BorshDeserialize on struct with a string?如何使用字符串在 struct 上实现 BorshDeserialize?
【发布时间】:2021-09-22 10:09:47
【问题描述】:

尝试通过 Solana 程序构建时,我收到此错误。谁能告诉我如何序列化字符串,因为我在我的结构中使用字符串。或者,如果在 Solana 程序中无法序列化字符串,我应该使用什么来代替 String?

结构:盒子

#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, PartialEq)]
pub struct Box {
    pub token_uris: [String; 3], 
    pub count: i32,
    pub title: String,
    pub description: String,
    pub image: String,
    pub price: i32,
    pub usd_price: i32,
    pub count_nft: i32,
    pub is_opened: bool,
}

错误日志:

15 | #[derive(Clone, Debug, BorshSerialize, BorshDeserialize, PartialEq)]
   |                                        ^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
   |
   = note: required because of the requirements on the impl of `AnchorDeserialize` for `[std::string::String; 3]`
   = help: see issue #48214
   = note: this error originates in the derive macro `BorshDeserialize` (in Nightly builds, run with -Z macro-backtrace for more info)

【问题讨论】:

  • 你能把这个问题发更多吗?
  • 嗨@Netwave 不确定您所说的 mre 是什么意思,您的意思是发布导致此问题的“结构”吗?刚刚将其添加到我的问题中,请检查
  • MRE = minimal reproducible example,一种让准助手不必发明或直觉与手头的问题可能或可能没有任何关系的事物的方法。创建 MRE 的过程通常还可以引导潜在的提问者找到他们请求的答案,因为这需要更好地了解错误情况和正在发生的事情。
  • 调用你的结构“盒子”并不理想,因为Box 有一个固有的 Rust 定义
  • 对,我已经修好了。谢谢:)

标签: string serialization rust deserialization solana


【解决方案1】:

谁能告诉我如何序列化字符串,因为我在我的结构中使用字符串。

问题不在于您使用的是字符串或结构中的字符串,而是您使用的是字符串在固定大小的数组中,因此编译器指向那个具体来说:

for `[std::string::String; 3]`

不是

for `String`

如果你去阅读the documentation for BorshDeserialize,你会发现:

impl<T> BorshDeserialize for [T; 3] where
    T: BorshDeserialize + Default + Copy, 

所以BorshDeserialize 仅适用于数组Default + Copy 类型。由于String 不是Copy,因此无法自动推导。

修复是:

  • 不使用固定大小的数组
  • 或在你的结构上手动实现BorshDeserialize,而不是尝试derive()

【讨论】:

  • 谢谢@Masking 这真的帮助我理解了这个问题,我可以确认这不是在结构中使用字符串而是在数组中使用字符串的问题。但是我需要将字符串存储在数组中我该怎么办?编译器建议使用 alloc::boxed::Box; 作为 ``` token_uris: Box ``` 是在数组中存储字符串的有效方法还是还有其他方法?
  • " 但是我需要将字符串存储在数组中,我该怎么办?"正如我告诉你的,手动实现反序列化器而不是派生它
  • "编译器建议使用 alloc::boxed::Box; 作为 ``` token_uris: Box ``` 是在数组中存储字符串的有效方式还是有其他方式好 ?”它完全没用,因为derive(BorshDeserialiser) 仍然无法工作。它不能与[String;3] 一起工作,如果你把它放在Box 中也没关系,不会更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 2021-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-13
  • 2017-01-18
相关资源
最近更新 更多