[易学易懂系列|rustlang语言|零基础|快速入门|(4)]
2021-10-01 09:15
标签:div 给一个用户 first 适用于 fir 快速 variable har 定义 Borrowing 继续讲讲另一个重要的概念:借用(borrowing), 什么是借用? 我们先来看前一文章([易学易懂系列|rustlang语言|零基础|快速入门|(3)])的代码 : let a = [1, 2, 3]; let b = a; println!("{:?} {:?}", a, b); // [1, 2, 3] [1, 2, 3] let a = vec![1, 2, 3]; let b = a; println!("{:?} {:?}", a, b); // Error; use of moved value: a 我们从上篇文章知道,第二段代码会报错,那怎么才能不报错呢? 我们改成以下代码: let a = vec![1, 2, 3]; let b = &a;//这里加了一个符号:&,表示借用 println!("{:?} {:?}", a, b); // correct 现在可以顺利通过傲娇的编程器女王的检查了!这就是“借用”的功效! 这里就出来一个rust语言的概念,叫借用(borrowing)。 来看下定义: 英语: Borrow (verb) To receive something with the promise of returning it. 翻译成中文:出来混,借了东西,迟早要还的! 那借用又分两类型: 1.共享借用(Shared Borrowing (&T)) 数据可以借用给一个或多个用户(或线程),但只准一个用户修改。 2.可变借用(Mutable Borrowing (&mut T)) 数据可以借用给一个用户,并只准这个用户修改,同时不准其他用户访问。 借用规则如下 : 1.数据同一时间,只能是其中一种借用,要么是共享借用(Shared Borrowing (&T)),要么是可变借用(Mutable Borrowing (&mut T))。 2.借用概念适用于复制类型(Copy type )和移动类型( Move type )。 请看如下代码: fn main() { let mut a = vec![1, 2, 3]; let b = &mut a; // &mut borrow of `a` starts here // ? // some code // ? // some code // ?} // &mut borrow of `a` ends here??fn main() { let mut a = vec![1, 2, 3]; let b = &mut a; // &mut borrow of `a` starts here // some code? println!("{:?}", a); // trying to access `a` as a shared borrow, so giving an error} // &mut borrow of `a` ends here??fn main() { let mut a = vec![1, 2, 3]; { let b = &mut a; // &mut borrow of `a` starts here // any other code } // &mut borrow of `a` ends here? println!("{:?}", a); // allow borrowing `a` as a shared borrow} 从上面代码,我们可以看出,借用,也是有“生命周期”的。 像这段代码 : fn main() { let mut a = vec![1, 2, 3]; let b = &mut a; // &mut borrow of a starts here // some code println!("{:?}", a); // trying to access a as a shared borrow, so giving an error } // &mut borrow of a ends here 为什么会报错?因为当最后一行代码: println!("{:?}", a); 要访问a时,a对数据的所有权,已经借用给b了。a已经没有数据所有权。所以报错。 那要怎么办? 加上大括号“{}”。 如下 : fn main() { let mut a = vec![1, 2, 3]; { let b = &mut a; // &mut borrow of `a` starts here // any other code } // &mut borrow of `a` ends here? println!("{:?}", a); // allow borrowing `a` as a shared borrow} 加上{}后,把借用,限定在大括号内,大括号结束后,b会把所有权还给a。 这时,a对数据有了所有权,就可以访问数据了! 那共享借用和可变借用有什么区别呢,请看代码如下 : 共享借用: fn main() { let a = [1, 2, 3]; let b = &a; println!("{:?} {}", a, b[0]); // [1, 2, 3] 1}??fn main() { let a = vec![1, 2, 3]; let b = get_first_element(&a);? println!("{:?} {}", a, b); // [1, 2, 3] 1}?fn get_first_element(a: &Vec) -> i32 { a[0]} 第一段代码: fn main() { let a = [1, 2, 3]; let b = &a; println!("{:?} {}", a, b[0]); // [1, 2, 3] 1 } 这里a借用给了b,为什么a还可以访问呢?因为a的类型是数组,是基本类型。这是复制类型,共享借用,只借用复制数据。所以,原来a还是拥有对原始数据的所有权。 第二段代码: fn main() { let a = vec![1, 2, 3]; let b = get_first_element(&a); println!("{:?} {}", a, b); // [1, 2, 3] 1 } fn get_first_element(a: &Vec) -> i32 { a[0] } 这里定义一个函数,get_first_element,返回值为数组中的第一个值。b从函数中得到值1。没有什么问题。 现在我们修改一下函数get_first_element的代码,如下 : fn get_first_element(a: &Vec) -> i32 { a[0]=9; a[0] } 这时,傲娇的编译器女王,又扔出一个错误给你: fn get_first_element(a: &Vec) -> i32 { | --------- help: consider changing this to be a mutable reference: &mut std::vec::Vec | a[0]=9; | ^ a is a & reference, so the data it refers to cannot be borrowed as mutable 这些错误信息很清楚地告诉你: 你现在是共享借用,共享借用只能共享数据,不能修改! 那要修改怎么办?用可变借用啊! 把代码修改为如下就可以了: fn main() { let mut a = vec![1, 2, 3]; let b = get_first_element(&mut a); println!("{:?} {}", a, b); // [1, 2, 3] 1 } fn get_first_element(a: &mut Vec) -> i32 { a[0]=9; a[0] } 可变借用: fn main() { let mut a = [1, 2, 3]; let b = &mut a; b[0] = 4; println!("{:?}", b); // [4, 2, 3]}??fn main() { let mut a = [1, 2, 3]; { let b = &mut a; b[0] = 4; }? println!("{:?}", a); // [4, 2, 3]}??fn main() { let mut a = vec![1, 2, 3]; let b = change_and_get_first_element(&mut a);? println!("{:?} {}", a, b); // [4, 2, 3] 4}?fn change_and_get_first_element(a: &mut Vec) -> i32 { a[0] = 4; a[0]} 以上,希望对你有用。 如果遇到什么问题,欢迎加入:rust新手群,在这里我可以提供一些简单的帮助,加微信:360369487,注明:博客园+rust[易学易懂系列|rustlang语言|零基础|快速入门|(4)]标签:div 给一个用户 first 适用于 fir 快速 variable har 定义 原文地址:https://www.cnblogs.com/gyc567/p/11910563.html
文章标题:[易学易懂系列|rustlang语言|零基础|快速入门|(4)]
文章链接:http://soscw.com/essay/108281.html