Type-erase owner in self-referential crates

huangapple go评论86阅读模式
英文:

Type-erase owner in self-referential crates

问题

我有一个结构体,并希望定义另一个引用它字段的结构体。

  1. struct Tweet {
  2. text: Text
  3. }
  4. #[ouroboros::self_referencing]
  5. struct BorrowedText<Owner> {
  6. owner: Arc<Owner>, // 确保在借用时不会被释放
  7. #[borrows(owner)]
  8. borrowed: &'this Text,
  9. }

可以有许多类型,其中包含Text作为成员。为了防止BorrowedText<T>创建过多的类型,我想要擦除所有者类型。

  1. #[ouroborus::self_referencing]
  2. struct BorrowedText {
  3. owner: Arc<dyn Any>, // 确保在借用时不会被释放
  4. #[borrows(owner)]
  5. borrowed: &'this Text,
  6. }

为此,我需要从owner: Arc<Tweet>获取&Text,然后将所有者上转换为Arc<dyn Any>。我无法使用ouroborus或owning_ref API(owning_ref甚至有专用的擦除类型,如ErasedBoxRef)来使这个工作。

是否有使用ErasedBoxRef或其他API来实现这一点的方法?或者我可以安全地执行下面的操作,而无需自引用的库?

  1. BorrowedText { owner: owner.clone(), borrowed: unsafe { (&owner.text) as (*const Text) } }
英文:

I have a struct, and want to define another struct that references its field.

  1. struct Tweet {
  2. text: Text
  3. }
  4. #[ouroboros::self_referencing]
  5. struct BorrowedText<Owner> {
  6. owner: Arc<Owner>, // make sure it's not deallocated while borrowing
  7. #[borrows(owner)]
  8. borrowed: &'this Text,
  9. }

There can be many types that have Text as a member. To prevent BorrowedText<T> from creating too many types, I would like to erase the owner type.

  1. #[ouroborus::self_referencing]
  2. struct BorrowedText {
  3. owner: Arc<dyn Any>, // make sure it's not deallocated while borrowing
  4. #[borrows(owner)]
  5. borrowed: &'this Text,
  6. }

For this I need to get &Text from owner: Arc<Tweet> and then upcast owner to Arc<dyn Any>. I couldn't make this work with ouroborus or owning_ref API (owning_ref even has dedicated erased-types like ErasedBoxRef).

Is there any way to achieve this with ErasedBoxRef or other API? Or can I just safely do the below without the need for self-referential crates?

  1. BorrowedText { owner: owner.clone(), borrowed: unsafe { (&owner.text) as (*const Text) } }

答案1

得分: 0

Manually unsafe-transmuting worked without a cost of dynamic downcast

  1. fn f(owner: Arc<Tweet>) {
  2. let borrowed = unsafe { std::mem::transmute::<&'_ _, &'static _>(&owner.text) };
  3. BorrowedText {
  4. owner: owner as Arc<dyn Send + Sync>,
  5. borrowed,
  6. }
  7. }
英文:

Manually unsafe-transmuting worked without a cost of dynamic downcast

  1. fn f(owner: Arc&lt;Tweet&gt;) {
  2. let borrowed = unsafe { std::mem::transmute::&lt;&amp;&#39;_ _, &amp;&#39;static _&gt;(&amp;owner.text) };
  3. BorrowedText {
  4. owner: owner as Arc&lt;dyn Send + Sync&gt;,
  5. borrowed,
  6. }
  7. }

huangapple
  • 本文由 发表于 2023年5月25日 02:30:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76326461.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定