Rust 学习笔记:修复所有权常见错误

Rust 学习笔记:修复所有权常见错误

错误一:返回栈上的引用

错误代码:

fn return_a_string() -> &String {
    let s = String::from("Hello World!");
    &s
}

fn main() {
    let value = return_a_string();
    println!("{}", value);
}

错误原因:

在 return_a_string 函数中,s 的生命周期只持续到函数结束。value 将指向一块未定义的内存。

解决方法 1:

在 Rust 中,数据必须比它的引用活的时间长。return_a_string 函数不应该返回引用,而应该转移所有权。

fn return_a_string() -> String {
    let s = String::from("Hello World!");
    s
}

fn main() {
    let value = return_a_string();
    println!("{}", value);
}

解决方法 2:添加生命周期说明符

fn return_a_string() -> &'static str {
    "Hello World!"
}

fn main() {
    let value = return_a_string();
    println!("{}", value);
}

static 表示字符串在整个程序运行期间一直存在。

错误二:没有足够的权限

错误代码:

fn stringify_name_with_title(name: &Vec<String>) -> String {
    name.push(String::from("Esq."));
    let full_name = name.join(" ");
    full_name
}

fn main() {
    let name = vec![String::from("Ferris")];
    let first = &name[0];
    stringify_name_with_title(&name);
    println!("{}", first);
}

错误原因:

stringify_name_with_title 函数的入参 name 是一个不可变变量,没有修改权限。

解决方法:创建一个可变变量

fn stringify_name_with_title(name: &Vec<String>) -> String {
    let mut full_name = name.join(" ");
    full_name.push_str(" Esq.");
    full_name
}

fn main() {
    let name = vec![String::from("Ferris")];
    let full = stringify_name_with_title(&name);
    println!("{}", full);
}

错误三:别名和可变性

错误代码:

fn add_big_strings(dst: &mut Vec<String>, src: &[String]) {
    let largest: &String = dst.iter().max_by_key(|l| l.len()).unwrap();
    for s in src {
        if s.len() > largest.len() {
            dst.push(s.clone());
        }
    }
}

错误原因:

原本 dst 是一个可变的引用,但 largest 作为一个不可变的引用指向了 dst 中的一个元素。后面 push 就会发生错误,因为暂时没有 dst 的写权限了。

解决方法:

不创建有关 dst 的不可变引用了。

fn add_big_strings(dst: &mut Vec<String>, src: &[String]) {
    let largest_len = dst.iter().max_by_key(|l| l.len()).unwrap().len();
    for s in src {
        if s.len() > largest_len {
            dst.push(s.clone());
        }
    }
}

错误四:从集合中拷贝一个元素(转移所有权)

错误代码:

fn main() {
    let v: Vec<i32> = vec![0, 1, 2];
    let n_ref: &i32 = &v[0];
    let n: i32 = *n_ref;

    let v: Vec<String> = vec![String::from("Hello world")];
    let s_ref: &String = &v[0];
    let s: String = *s_ref;
}

错误原因:

不可以通过引用来获得所有权!

i32 具有 Copy Trait,在解引用的时候完成了复制。

String 没有 Copy Trait,在解引用时尝试获得所有权,失败。

解决方法:

通过 clone 创建一个字符串的副本。

fn main() {
    let v: Vec<i32> = vec![0, 1, 2];
    let n_ref: &i32 = &v[0];
    let n: i32 = *n_ref;

    let v: Vec<String> = vec![String::from("Hello world")];
    let s_ref: &String = &v[0];
    let s: String = v[0].clone();
}

错误五:对元组的引用

错误代码:

fn get_first(name: &mut (String, String)) -> &String {
    &name.0
}

fn main() {
    let mut name = (String::from("A"), String::from("B"));
    let first = get_first(&mut name);
    name.1.push_str(", Esq.");
    println!("{first} {}", name.1);
}

错误原因:

Rust 只关注函数的声明那一行,它发现 get_first 函数返回的是一个不可变的引用,它并不关心引用的是 name.0 还是 name.1,将 name.0 和 name.1 的写权限都暂时剥夺了,name.1 就不能修改了。

解决方法:

直接引用 name.0,因为元组中的每个元素的所有权都是独立的,这里只是将 name.0 和 name 的写权限暂时剥夺了,只修改 name.1 是不会报错的。

fn main() {
    let mut name = (String::from("A"), String::from("B"));
    let first = &name.0;
    name.1.push_str(", Esq.");
    println!("{first} {}", name.1);
}

错误六:修改数组中的元素

错误代码:

fn main() {
    let mut a = [0, 1, 2, 3];
    let x = &mut a[1];

    *x += 1;
    
    let y = &a[2];
    *x += *y;
    
    println!("{a:?}");
}

错误原因:

对 a 中元素创建了一个可变引用后,a 就暂时失去了读、写、拥有权限,只有 x 有权限。后面想再创建一个对 a 中元素的不可变引用,y 又想要获取 a 的读权限,就出错了。

修改:

fn main() {
    let mut a = [0, 1, 2, 3];
    let x = &mut a[1];

    *x += 1;
    
    // let y = &a[2];
    // *x += *y;
    
    println!("{a:?}");
}
本指南详细阐述基于Python编程语言结合OpenCV计算机视觉库构建实时眼部状态分析系统的技术流程。该系统能够准确识别眼部区域,并对眨眼动作与持续闭眼状态进行判别。OpenCV作为功能强大的图像处理工具库,配合Python简洁的语法特性与丰富的第三方模块支持,为开发此类视觉应用提供了理想环境。 在环境配置阶段,除基础Python运行环境外,还需安装OpenCV核心模块与dlib机器学习库。dlib库内置的HOG(方向梯度直方图)特征检测算法在面部特征定位方面表现卓越。 技术实现包含以下关键环节: - 面部区域检测:采用预训练的Haar级联分类器或HOG特征检测器完成初始人脸定位,为后续眼部分析建立基础坐标系 - 眼部精确定位:基于已识别的人脸区域,运用dlib提供的面部特征点预测模型准确标定双眼位置坐标 - 眼睑轮廓分析:通过OpenCV的轮廓提取算法精确勾勒眼睑边缘形态,为状态判别提供几何特征依据 - 眨眼动作识别:通过连续帧序列分析眼睑开合度变化,建立动态阈值模型判断瞬时闭合动作 - 持续闭眼检测:设定更严格的状态持续时间与闭合程度双重标准,准确识别长时间闭眼行为 - 实时处理架构:构建视频流处理管线,通过帧捕获、特征分析、状态判断的循环流程实现实时监控 完整的技术文档应包含模块化代码实现、依赖库安装指引、参数调优指南及常见问题解决方案。示例代码需具备完整的错误处理机制与性能优化建议,涵盖图像预处理、光照补偿等实际应用中的关键技术点。 掌握该技术体系不仅有助于深入理解计算机视觉原理,更为疲劳驾驶预警、医疗监护等实际应用场景提供了可靠的技术基础。后续优化方向可包括多模态特征融合、深度学习模型集成等进阶研究领域。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值