我正在使用Dioxus构建一个UI.该UI在很大程度上依赖于来自第三方库的 struct .此 struct 不实现克隆.按下按钮时需要修改 struct .请考虑这个简化的示例:

use dioxus::prelude::*;

struct ThirdPartyStruct(i64);

impl ThirdPartyStruct {
    fn add_one(&mut self) {
        self.0 += 1;
    }
}

fn app(cx: Scope) -> Element {
    let third_party_struct = use_state(cx, || ThirdPartyStruct(0));

    cx.render(rsx! {
        button {
            onclick: move |_| third_party_struct.make_mut().add_one(),
            "Click me!"
        }
        p {
            "{third_party_struct.get().0}"
        }
    })
}

这不能编译,因为make_mut需要为ThirdPartyStruct实现克隆.真实的ThirdPartyStruct并非如此简单,必须使用真实的add_one(所以像"使用+ 1代替"这样的解决方案是无效的).手工实现克隆也是不可行的.

我try 了很多方法,包括用于修改包含的 struct 的UseState struct 的大多数方法.它们要么都需要按值修改 struct (比如调用+ 1而不是+= 1),要么需要实现克隆.

推荐答案

我能想到的解决这个问题的唯一方法是将 struct 包装在RefCell中.这可能不是最安全的内存方式,但它是works.

这样做的副作用是状态不知道它已经更改,因此您需要在每次使用cx.needs_update()调用变异函数时手动将组件标记为脏.

fn app(cx: Scope) -> Element {
    let third_party_struct = use_state(cx, || RefCell::new(ThirdPartyStruct(0)));

    cx.render(rsx! {
        button {
            onclick: move |_| {
                third_party_struct.borrow_mut().add_one();
                cx.needs_update();
            },
            "Click me!"
        }
        p {
            "{third_party_struct.get().borrow().0}"
        }
    })
}

值得注意的是,我没有try 过这个与sysinfo机箱,但它的工作与您的MRE.

Rust相关问答推荐

有没有方法处理rust中嵌套的ok_or()?

为什么我们不能通过指针算法将Rust原始指针指向任意地址?'

将已知大小的切片合并成一个数组,

MutexGuard中的过滤载体不需要克隆

为什么reqwest以文本形式下载二进制文件?

Tokio_Postgres行上未显示退回特性的生存期,且生命周期 不够长

创建Rust中元对象协议的动态对象 Select /重新分配机制

如何在函数中返回自定义字符串引用?

Rust中WPARAM和VIRTUAL_KEY的比较

Rust从关联函数启动线程

为什么特征默认没有调整大小?

借来的价值生命周期 不够长,不确定为什么它仍然是借来的

UnsafeCell:它如何通知 rustc Select 退出基于别名的优化?

将 &str 或 String 保存在变量中

max(ctz(x), ctz(y)) 有更快的算法吗?

有什么方法可以通过使用生命周期来减轻嵌套生成器中的当生成器产生时borrow 可能仍在使用错误?

使用 lalrpop 在 rust 中解析由 " 引用的字符串

按下 Ctrl + C 时优雅地停止命令并退出进程

如何将这些测试放在一个单独的文件中?

如何在 Rust 中返回通用 struct