fnlargest_i32(list:&[i32])->&i32{letmut largest =&list[0];for item in list {if item > largest {
largest = item;}}
largest
}fnlargest_char(list:&[char])->char{letmut largest = list[0];for&item in list.iter(){if item > largest {
largest = item;}}
largest
}fnmain(){let number_list =vec![34,50,25,100,65];let result =largest_i32(&number_list);println!("The largest number is {}", result);let char_list =vec!['y','m','a','q'];let result =largest_char(&char_list);println!("The largest char is {}", result);}
泛型初试
/*
error
fn largest<T: std::cmp::PartialOrd>(list: &[T]) -> &T {}
泛型T没实现PartialOrd,标准库 i32,char 都实现了PartialOrd
所以,泛型T: PartialOrd + Copy,可以解决
error: the trait bound `T: std::cmp::PartialOrd` is not satisfied
*/// fn largest<T>(list: &[T]) -> &T {// let mut largest = &list[0];// for item in list {// if item > largest {// largest = item;// }// }// largest// }fnlargest<T:PartialOrd+Copy>(list:&[T])->&T{letmut largest =&list[0];for item in list {if item > largest {
largest = item;}}
largest
}fnmain(){let result =largest(&number_list);println!("The largest number is {}", result);let result =largest(&char_list);println!("The largest char is {}", result);}
fnreturns_summarizable()->implSummary{Tweet{
username:String::from("horse_ebooks"),
content:String::from("of course, as you probably already know, people"),
reply:false,
retweet:false,}}
3.生命周期确保引用有效
3.1生命周期避免了悬垂引用
生命周期的主要目标是避免悬垂引用,后者会导致程序引用了非预期引用的数据
fnmain(){let r;{let x =5;
r =&x;// error, borrowed value does not live long enough}// 此处,x就释放内存println!("r: {}", r);}
3.2借用检查器
rust编译器有一个借用检查器,比较作用域来确保所有的借用都是有效的
fnmain(){// let r;// {// let x = 5;// r = &x;// }// println!("r: {}", r);let y =5;let e =&y;println!("e: {}", e);// e: 5}
3.3函数中的泛型生命周期
// 借用检查器自身同样也无法确定,因为它不知道 x 和 y 的生命周期fnmain(){let string1 =String::from("abcd");let string2 ="xyz";let result =longest(&string1, string2);println!("The longest string is {}", result);}fnlongest(a:&str, b:&str)->&str{if a.len()> b.len(){
a
}else{
b
}}
fnmain(){let string1 =String::from("abcd");let string2 ="xyz";let result =longest(&string1, string2);println!("The longest string is {}", result);}fnlongest<'a>(a:&'astr, b:&'astr)->&'astr{if a.len()> b.len(){
a
}else{
b
}}
注意事项
fnmain(){// string2 在作用域结束前有效let string1 =String::from("abcd");{let string2 ="xyz";let result =longest(&string1, string2);println!("The longest string is {}", result);}// let string1 = String::from("abcd"); // let result; // {// let string2 = "xyz"; // result = longest(&string1, string2); // }// // string2 需要知道外部作用域结束都是有效的,longest函数返回的是一个引用,所以result需要知道string2的作用域结束// // 否则编译器会报错// println!("The longest string is {}", result); }fnlongest<'a>(a:&'astr, b:&'astr)->&'astr{if a.len()> b.len(){
a
}else{
b
}}
3.6深入理解生命周期
指定生命周期参数的正确方式依赖函数实现的具体功能
返回的引用 没有 指向任何一个参数,那么唯一的可能就是它指向一个函数内部创建的值
它将会是一个悬垂引用,因为它将会在函数结束时离开作用域
fnlongest<'a>(x:&str, y:&str)->&'astr{let result =String::from("really long string");
result.as_str()}
3.7结构体定义中的生命周期注解
定义的结构体全都包含拥有所有权的类型
定义包含引用的结构体,不过这需要为结构体定义中的每一个引用添加生命周期注解
// 定义包含引用的结构体,需要为结构体定义中的每一个引用添加生命周期注解structImportantExcerpt<'a>{
part:&'astr,}fnmain(){let novel =String::from("Call me Ishmael. Some years ago...");let first_sentence = novel.split('.').next().expect("Could not find a '.'");let i =ImportantExcerpt{ part: first_sentence };println!("{}", i.part);}