多个closure引用同一个变量,并且可能需要mut borrow

闭包设计原理:词法环境、捕获模式与内存模型 闭包是现代编程语言中函数作为一等公民的核心体现,其本质是函数体与其定义时词法环境的不可分割绑定。理解闭包需从词法作用域出发——变量查找依赖源码结构而非调用栈,这是闭包语义成立的前提;进而涉及捕获机制,即外部变量如何被安全引用,包括只读捕获、可变捕获与显式所有权转移等关键设计选择;在内存层面,闭包实现直接受制于语言的内存模型,如垃圾回收堆分配(JavaScript)、引用计数(C#)或编译期所有权系统(Rust),每种方案对应不同的运行时开销与安全边界。这些原理共同支撑着React的useCallback、R 阅读详情

目前在实现一个事件系统,事件采用保存closure的方式实现,这其中遇到一个比较棘手的问题就是如果其中一个closure用&mut方式捕捉了一个变量,那么其他closure就不可以再用任何方式捕捉这个变量(rust的borrow check系统),并且如果要&mut捕捉还需要把closure的类型写成FnMut,类似这种: add_event<F>(&mut self,f:F) where F:FnMut(...){}
目前折中的一个方法就是用Rc<RefCell<T>>的方式了,这个就是最终用户用起来很烦,大量的变量要用这种方式包裹。

use std::rc::Rc;
use std::cell::RefCell;

enum MyCall<'a>{
    Click(Box<Fn(i32)->i32 + 'a>),
    Down(Box<Fn(i32,i32)->i32 + 'a>),
    None,
}

struct Foo<'a>{
    calls:Vec<MyCall<'a>>,
}

impl<'a> Foo<'a>{
    fn new()->Foo<'a>{
        Foo{
            calls:Vec::new(),
        }
    }

    fn add_click<F>(&mut self,f: F)where F:Fn(i32)->i32+'a{
        self.calls.push(MyCall::Click(Box::new(f)));
    }

    fn do_call(&self){
        if let MyCall::Click(ref c) = self.calls[0] {
                println!("{}",(*c)(100));
        }

        if let MyCall::Click(ref c) = self.calls[1] {
                println!("{}",(*c)(100));
        }
    }
}

#[derive(Debug)]
struct A(i32);

#[derive(Debug)]
struct Bar{
    i:Rc<RefCell<A>>,
}

fn main(){
    let mut b = Bar{i:Rc::new(RefCell::new(A(200)))};
    let mut f = Foo::new();
    f.add_click(|i|{
        let bi = b.i.clone();
        let mut mbi = bi.borrow_mut();
        (*mbi).0 = 2000;
        (*mbi).0
        //b.0 = 100;
        //b.0
    });
    f.add_click(|i|{
        let bi = b.i.clone();
        let mut mbi = bi.borrow_mut();
        (*mbi).0 = 20000;
        (*mbi).0
    });
    f.do_call();
    println!("{:?}",b);
}

Play地址:http://is.gd/vdtWiG

输出:

2000
20000
Bar { i: RefCell { value: A(20000) } }

其实不用Rc也可以,大家可以看看这个,我目前对这个机制也不是太熟悉:
http://is.gd/78HF1Y

Rust + Tauri调用鸿蒙系统原生API,打通桥接实战经验总结 真不容易啊,网上这方面资料很少,探索尝试了很久终于打通了调用鸿蒙原生API的方法。这有什么用?使用Tauri做跨端APP是个不错的技术方案,可以一次可以跨N端。但是呢肯定避免不了依赖和使用系统的原生API来扩展能力。当前Tauri在android和ios端,官方都有插件支持。但鸿蒙还不支持,有待探索。正在(或即将)把 Tauri 应用往鸿蒙(HarmonyOS)上搬、想调用系统原生能力(相册、分享、通知、剪贴板……)的开发者。本文是一篇实战记录,不是官方文档复述。 阅读详情

相关推荐

Rust: RefCell, Rc

借助LeetCode: 563整理一下我对RefCell, Rc基本使用方法的理解,肯定会有疏漏,希望大家指正:) 重点:Rc, RefCell结构的使用|自动解引的过程 非重点:算法 代码 impl Solution { pub fn find_tilt(root: Option<Rc<RefCell<TreeNode>>>) -> i32 { let (_weight, tilt) = Solution::weight_tilt(&amp

weixin_47207476的博客 1419

rust学习(BorrowMut异常)

一个cell貌似不能同时被借用两次,注意!所以如果出现这类错,也要考虑是否有多线程的问题。但是如果一直拿着borrow_mut的句柄,就会报错。不要长期持有borrow_mut的句柄。

一个白馒头的专栏 636

【信息科学与工程学】计算机科学与自动化——第二十四篇 编译器10——编译原理与词法分析02

链接时优化:全局DCE(579)、LTO(580)安全编译:CFI(581、586)、ASan(582)、UBSan(583)、MSan(584)、TSan(585)、CET(587)、PAC(588)、MTE(589)、SFI(590)、Wasm沙箱(591)侧信道与秘密:侧信道缓解(592)、常量时间(593)、秘密清理(594)内存安全:ASLR(595)、栈保护(596)、整数溢出检测(597)、除零检测(598)、空指针检测(599)、数组边界检查(600)至此编号达到600。

weixin_49199313的博客 194

Rust从入门到实战系列一百七十九:RefCell<T> 在运行时记录借用

当创建不可变和可变引用时,我们分别使用 & 和 &mut 语法。对于 RefCell 来说,则是 borrow 和borrow_mut 方法,这属于 RefCell 安全 API 的一部分。borrow 方法返回 Ref 类型的智能指针,borrow_mut 方法返回 RefMut 类型的智能指针。这两个类型都实现了 Deref,所以可以当作常规引用对待。RefCell 记录当前有多少个活动的 Ref 和 RefMut 智能指针。每次调用 borrow,RefCell。

wanmeijuhao的博客 1030

手把手教你用Python分析OpenFAST仿真结果:pyDatView处理.out文件与数据可视化技巧

本文详细介绍了如何使用Python中的pyDatView工具分析OpenFAST仿真结果,包括数据加载、质量检查、时域与频域分析、多工况对比及自动化报告生成。通过优化技巧和可视化方法,帮助工程师高效处理.out文件,提升风机性能分析的准确性和效率。

weixin_29311017的博客 182

激光定位算法竞技场:hdl_localization与Cartographer/AMCL的横向技术解剖

本文深入对比了hdl_localization、Cartographer和AMCL三种激光定位算法的技术原理与性能表现。通过UKF-NDT融合、图优化和粒子滤波等核心技术,分析了各算法在结构化环境、动态环境和大尺度场景下的适应性。实验数据表明,Cartographer在全局一致性上表现最优,而AMCL在动态环境中更具鲁棒性。文章还提供了算法选型指南和参数调优技巧,为工程实践提供参考。

weixin_29062865的博客 365

Rust常用特型之Borrow和BorrowMut特型

Rust常用特型之Borrow和BorrowMut特型学习

天草降临的博客 1736

Docker一键部署Synopsys EDA全家桶(VCS/Verdi 2018版)保姆级教程

本文提供了一份详尽的Docker容器化部署Synopsys EDA工具链(VCS/Verdi 2018版)的保姆级教程。通过环境隔离与标准化,解决传统安装的依赖冲突问题,并重点攻克了容器内GUI图形界面显示的核心难题。教程涵盖从Docker基础安装、镜像获取、容器启动配置,到使用X11转发或VNC实现Verdi完美显示的完整实践,旨在帮助芯片设计工程师快速构建稳定、可移植的一键化EDA工作环境。

weixin_29281941的博客 196

Rust常用知识点积累

【代码】Rust常用知识点积累。

ytuglt的博客 406

AMBA总线—APB总线协议详解

文章目录一、APB总线介绍1.1.什么是APB总线1.2.典型的基于 AMBA 总线的系统架构1.3.APB信号列表(重点)二、APB总线传输(时序)2.1.APB 状态机2.2.写操作(重要)2.3.读操作(重要)2.4.APB组件接口(重要)2.4.1.APB Bridge框图2.4.2.APB Slave框图三、APB到AHB的接口3.1.读操作3.2.写操作3.3.读写交替传送 一、APB...

Mr.翟的博客 4万+

车辆横向控制MPC实战:从‘老王模型’到CasADi求解的保姆级避坑指南

本文详细解析了车辆横向控制MPC的实战应用,从经典动力学模型选择到CasADi求解器的优化配置,提供了一套完整的避坑指南。重点介绍了车辆动力学模型的验证要点、CasADi环境的高效配置技巧以及MPC问题建模的核心要素,帮助开发者快速实现稳健的横向控制方案。

weixin_42524499的博客 346

rust智能指针与内部可变性

彻底理解rust智能指针、内部可变性,浅析链表。

ustclyang的博客 2134

制造业私有化LLM部署实战:从RAG到智能体,构建企业专属知识大脑

大型语言模型(LLM)作为人工智能的核心技术,通过在海量文本数据上进行预训练,具备了强大的语言理解和生成能力。其原理在于基于Transformer架构,通过自注意力机制捕捉长距离语义依赖。这一技术价值在于能将非结构化信息转化为可计算、可推理的知识,从而赋能企业实现知识的高效管理与应用。在制造业等强数据安全与知识密集型领域,私有化部署的LLM结合检索增强生成(RAG)和智能体(Agent)技术,能够深入业务流程,构建安全、专属的智能知识中枢。本文聚焦于如何利用Qwen、LangChain、向量数据库等技术栈,

weixin_42523711的博客 247

Rust function & closure

文章目录函数与方法闭包输入函数作为输出参数 函数与方法 struct Point{ x:f64, y:f64, } impl Point{ // 静态方法(static method) fn origin() ->Point { Point{ x:0.0,y:0.0} } fn new(x:f64,y:f64)->Point{ Point{x:x, y:y} } } struct Rectangle{

红叶谷 wsp_1138886114的博客 793

【Q1/论文复现】:利用 CHARLS 数据库考察抗高血压药物依从性和认知衰退

摘要: 北京大学团队基于CHARLS数据(2011-2018)的纵向研究发现,抗高血压药物高依从性能显著延缓中国45岁及以上社区中老年人的认知衰退。研究表明,坚持服药者7年内全局认知衰退速度降低0.014SD/年,记忆功能衰退减缓0.023SD/年,效果接近正常血压人群水平。研究还提示社会经济地位(SES)可能通过影响用药依从性间接调控认知衰老进程。该成果为高血压管理对认知保护提供了人群级证据,发表于《BMC Medicine》(DOI:10.1186/s12916-025-03949-8)。

dingdianbangni的博客 808

[RAM] DRAM 导论:DDR4 | DDR5 | LPDDR5 | GDRR6 | HBM 应运而生

有数据的地方就有存储, 内存是谁都离不开的产品。而动态随机存取存储器(DRAM)作为一种常见的内存。本博客将介绍DRAM的基本概念、工作原理、优缺点以及应用领域等方面。

串起点滴 3917

聊聊Rust中的闭包

前两天敲着敲着代码,编译器突然弹出了这么一条错误信息: let push: |&str| -> () cannot borrow `push` as mutable, as it is not declared as mutable

wangjun861205的博客 1242

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Rust所有权机制:核心概念与实战技巧

内存安全是现代编程语言的核心诉求之一,Rust通过独特的所有权机制在编译期就保证了内存安全,无需垃圾回收。所有权系统基于三条简单规则:每个值有唯一所有者、值随所有者离开作用域被释放、赋值操作转移所有权。这种机制不仅解决了C/C++中常见的内存安全问题(如空指针、数据竞争等),还为并发编程提供了天然安全保障。在实际开发中,理解所有权转移、借用规则和生命周期等概念至关重要,特别是在处理字符串切片、结构体设计和函数参数传递等场景时。Rust的智能指针(如Rc、Arc)和Copy trait进一步扩展了所有权系统的

weixin_33850890的博客 413

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

显式闭包捕获:从隐式依赖到生命周期安全的语言设计对比

闭包是现代编程语言中函数式编程的核心机制,而捕获列表决定了闭包如何访问外部变量。默认的隐式捕获虽然简洁,却容易引发生命周期悬空、共享状态竞争和隐藏依赖等问题。显式捕获通过语法层面明确定义按值、按引用、弱引用或所有权转移,让闭包的行为可预测、可审查。从C++的初始化捕获、Swift的weak/unowned,到Rust的move与所有权检查,不同语言在捕获粒度与安全性之间做出不同权衡。理解这些设计差异,有助于在异步、并发或资源管理场景下正确使用lambda表达式。文章对比主流语言的捕获实现,提炼工程可落地的设

weixin_30443747的博客 410

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Rust 程序设计语言学习——函数式语言功能:迭代器和闭包

Rust 的闭包(closures)是可以保存在一个变量中或作为参数传递给其他函数的匿名函数。可以在一个地方创建闭包,然后在不同的上下文中执行闭包运算。不同于函数,闭包允许捕获被定义时所在作用域中的值。迭代器(iterator)负责遍历序列中的每一项和决定序列何时结束的逻辑。当使用迭代器时,我们无需重新实现这些逻辑。

洪伟的专栏 1790

Rust项目AI代码泛滥?从工具链到审查守好质量关

Rust以严格的编译器检查和内存安全著称,其所有权与生命周期机制在编译期就拦截了大量潜在错误。然而,当AI辅助编程工具批量生成代码时,这些“看起来正确”的代码往往在cargo check阶段就暴露出借用冲突、错误处理潦草、并发模型混乱等问题,给项目维护者带来沉重的PR审查压力。要化解这一矛盾,关键在于建立从提示词约束、自动化质量门禁到人工审查checklist的全流程防线:通过cargo fmt统一格式,用cargo clippy拦截代码坏味道,再结合CI流水线将低质量PR拒之门外。同时,合理设计提示词让A

weixin_34068198的博客 361

AI时代程序员的核心能力:从写代码到校准意图

编程已不再等同于手写语法正确的代码,而是一种将业务需求精准转化为技术实现的‘意图翻译’能力。其底层支撑是计算机系统原理、运行时模型与领域约束的深度理解——例如 Rust 中所有权与生命周期的权衡,或前端中 React 渲染管线与任务调度的协同机制。这种能力决定了开发者能否在 AI 生成代码后快速识别风险、修正偏差并做出不可替代的技术决策。它直接关联性能优化、故障根因穿透、跨栈架构选型等高价值工程实践,尤其在工业级系统、金融合规、实时视觉等对精度与稳定性要求严苛的场景中成为关键分水岭。本文聚焦‘意图校准’这一

weixin_33726313的博客 468

SpringBoot+Vue构建高并发图书电商平台实战

电商系统开发中,高并发与数据一致性是核心挑战。通过SpringBoot的自动配置和事务管理能力,结合Vue的组件化开发模式,可以快速构建稳定高效的全栈应用。在库存管理等关键场景,Redis+Lua脚本实现原子操作避免超卖,MySQL的DECIMAL类型确保金额计算精确。本文以图书电商为例,详解ISBN管理、树形分类设计等特色实现,分享Jenkins自动化部署与Vue性能优化经验,为中小型电商系统开发提供可复用的技术方案。

weixin_34345753的博客 388

RUST笔记:初识RefCell

初识RefCell

m0_54948954的博客 713

js的闭包(Closure)是什么?【隐藏一个变量,间接访问它】

什么是「闭包」。 「闭包」的作用是什么 假设上面三行代码在一个立即执行函数中(为简明起见,我就不写立即执行函数了,影响读者理解)。 三行代码中,有一个局部变量 local,有一个函数 foo,foo 里面可以访问到 local 变量。 好了这就是一个闭包: 「函数」和「函数内部能访问到的变量」的总和,就是一个闭包。 就这么简单。 有的同学就疑惑了,闭包这么简单么? 「我听说闭包是需要函数套函数,然后 return 一个函数的呀!」 比如这样: function foo(){ var local.

weixin_46037781的博客 485

Rust 中的指针:Box、Rc、Cell、RefCell

Rust 中的指针:Box、Rc、Cell、RefCell 作者:许野平 2022-02-21 Rust 自身具有 &、* 操作符,可以实现变量引用和解引用。为什么又搞出这几个类型的指针呢?原因就是想突破 Rust 坚持的”共享不可写、可写不共享“的原则。我们看看 Rust 编译器的”道德底线“是如何被一步一步突破的吧。 1 Box 类型 我在《 Rust 的 Box指针》一文中详细讨论了 Box 的特点。看一个简单的例子: fn main() { let x = String::from(

程序猿视角 2939
上一篇: Sized和?Sized的作用
下一篇: Rc与Box区别
varding
博客等级 码龄17年 115粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值