1.RUST中每个值都有一个所有者,每次只能有一个所有者
String::from函数会为字符串hello分配一块内存
内存示例如下:
在内存分配前调用s1正常输出
在分配s1给s2后调用报错
因为s1分配给s2后,s1的指向自动失效
s1被move到s2 s1自动释放
字符串克隆使用
所有整数类型,布尔类型 ,所有浮点类型,字符类型,元组,等,这些类型实现了copy特性
在分配时原来的变量值不会被移动
如果元组中也实现Copy
.例如, (i32, i32)
实现Copy
,那么不会被移动
但(i32, String)
不实现copy将会被移动,因为String不实现copy特性
复制与移动示例
字符串类型未实现copy特性,会被移动
可使用clone或者返回字符串所有权
克隆
返回字符串所有权:
所有权转移
完整示例代码:
fn main() {println!("RUST语言内存与堆栈关系认识(值所有权)");let str = "HelloWorld";//str指针指向HelloWorld的内存println!("{}",str);//String::from会请求内存let str1 =String::from("Hello");//不可变let mut str2=String::from("Ok,");//可变str2.push_str(str);//连接字符串println!("{}",str2);//在Rust中一旦拥有内存的变量超出范围,内存就会自动返回,RUST会调用drop函数释放内存let x=888;let y=x;//y会复制x的副本println!("{},{}",x,y);let s1=String::from("hello");//会分配一块内存来保存字符串helloprintln!("分配s1给s2前:{}",s1);let s2=s1;println!("{}",s2);//s1被move到s2 s1自动释放//要使s1分配给s2后,不释放,使用clone方法let s1 = String::from("OK");let s2=s1.clone();println!("{},{}",s1,s2);let mystr=String::from("Hello,RUST");//mystr指向Hello,RUSTlet mystr2=mystr.clone();//在被移动前克隆副本test_allow_string(mystr);//已移动到函数中,此时mystr无效//println!("{}",mystr);//因为mystr已移动,这里会报错println!("{}",mystr2);//因为mystr克隆副本let mynum:i64 = 999;test_allow_num(mynum);//会复制mynum副本到函数中println!("{}",mynum);let mystr3 = mystr2.clone();//此处调用后mystr2所有权被移动println!("{}",test_allow_string_return(mystr2));//通过元组转移所有权let (s,n) = test_allow_string_return_more(mystr3);println!("{},{}",s,n);
}fn test_allow_string(str:String){println!("test_allow_string:{}",str);
}//返回传入的字符串
fn test_allow_string_return(str:String) -> String{str
}//传入字符串,返回元组
fn test_allow_string_return_more(str:String) -> (String,usize){let n = str.len();(str,n)//返回元组
}fn test_allow_num(num:i64){println!("test_allow_num:{}",num);
}