mutable references and mut in function
fn add_is_great(country_name: &mut String){
country_name.push_str(" is great!");
println!("Now it says: {}", country_name);
}
fn main(){
let mut my_country = "캐나다".to_string();
/*
add_is_great(my_country); // by value
add_is_great(&my_country); // by reference
*/
add_is_great(&mut my_country); // by mutable reference
add_is_great(&mut my_country);
}
/* Output
Now it says: 캐나다 is great!
Now it says: 캐나다 is great! is great!
*/
비슷하지만 완전 다른 개념!
fn add_is_great(mut country_name: String){ // take by value, declare as mutable
country_name.push_str(" is great!");
println!("Now it says: {}", country_name);
}
fn main(){
let my_country = "대한민국".to_string();
add_is_great(my_country); // 여기서 소유권이 넘어감!
}
Ownership and copy types
fn prints_number(number: i32){
println!("{}", number);
}
fn prints_string(input: String){
println!("{}", input);
}
fn main(){
let my_number = 8;
prints_number(my_number); // number 는 copy type(copy 하기 쉬움)이라 소유권 신경쓸 필요 없음!
prints_number(my_number);
let my_country = "Austria".to_string();
prints_string(my_country); // 여기서 소유권 넘어감!
prints_string(my_country); // 그래서 여기서 오류남!
/*
오류가 안나게 하려면 .clone 메서드를 사용
prints_string(my_country.clone());
clone은 빠르게 컴파일을 하고싶을 때 많이 사용함!
*/
}
uninitialized variable & loop
fn main(){
/*
let my_number; // 는 불가능!
*/
/*
let my_number: i8; // 는 사용은 가능!
println!("{}", my_number); // 하지만 여기서 에러남!! value가 initialized 되지 않았기 때문
*/
}
fn loop_then_return(mut counter: i32) -> i32 {
loop {
counter += 1;
if counter % 50 == 0 {
break;
}
}
counter
}
fn main(){
let my_number;
{
let x = loop_then_return(43);
my_number = x
}
println!("{}", my_number); // my_number가 위에서 initialized 됐기 때문에 오류가 발생하지 않음
}
하지만 이 패턴은 잘 안사용!
기존의 코드(C 등등..)을 사용하던 개발자들의 편의를 위해 rust에서 허용하는 기능!
Arrays
fn main(){
let array = ["one", "two"]; // type -> [&str; 2]
let array2 = ["one", "two", "Five"]; // type -> [&str; 3]]
// array 와 array2 는 다른 타입이라 비교 자체가 불가능!!
// array 는 추가할 수 없고, 삭제할 수 없고..
}
fn main(){
let array = ["one", "two"];
//type을 보기 위한 꼼수 : 존재하지 않는 method 사용 ㅋㅋ
array.zxcvzxcvasdfasdfasd(); // >> 여기서 [type]에 대한 method 가 없습니다! 라고 에러를 뱉음
}
indexing 은 다른 언어와 비슷!
fn main(){
let array = ["one", "two"];
println!("{}", array[0]); // "one" 출력
/*
없는 index 출력하면 오류남 !
*/
}
Slices
fn main(){
let seasons = ["봄", "여름", "가을", "겨울"];
println!("{:?}", seasons[0..2]); // 에러 발생!! dynamically sized type 이라 사이즈를 알 수 없기 때문에 오류가 발생함
}
fn main(){
let seasons = ["봄", "여름", "가을", "겨울"];
println!("{:?}", &seasons[0..2]); // reference 를 사용해서 넘길 수 있음!
/*
&seasons[0..=2] // up to and including
&seasons[..] // all
&seasons[3..] // from 4th index
&seasons[..4] // up to 5th index
*/
}
"누구나 좋아하는" Vecs
= vector
fn main(){
let my_string = String::new(); // string 선언!
let mut my_vec: Vec<String> = Vec::new();
}
fn main(){
let name1 = String::from("Windy);
let name2 = String::from("Gomesy");
let mut my_vec = Vec::new();
// Vec::from() 도 사용가능
/*
vec![] 로 더 쉽게 사용가능!
예를 들어
let my_vec = vec![name1, name2];
*/
my_vec.push(name1);
my_vec.push(name2);
println!("My cats are {:?}", my_vec);
}
Traits = 초능력
fn main(){
let my_name = String::from("Dave Macleod"); // from 사용!
let my_city: String = "Seoul".into(); // into 사용!! "Seoul"은 String이 아닌 &str 인데 String 변수에 맞게 변환!?
}
fn main(){
let my_vec = Vec::from([8,9,10]); // type : [i32; 3]
}
tuples : 여러가지 타입을 한 가지 타입으로 표현하고 싶을 때 사용!
fn main(){
let my_tuple = (8, "Dave MacLeod", vec![8,9,10]);
my_tuple.asdfasdfasdf(); // 없는 method 로 컴파일러에게 타입 물어보기 ㅋㅋ
// -> no method named `asdfasdfasdf` found for tuple `({integer}, &str, Vec<{integer}>)`
// type : tuple
}
tuple indexing
/*
Array 와 Vector 에서 indexing 은 array[0], vec[0] 이런식으로 대괄호를 사용해서 인덱싱
tuple은 대괄호를 사용하지 않고 .0 .1 이런식으로 사용
*/
fn main(){
let random_tuple = ("Here is a name", 8, vec!['a'], 'b', [8,9,10], 7.7);
println!("Inside the tuple");
println!("0 : {:?}", random_tuple.0);
println!("1 : {:?}", random_tuple.1);
println!("2 : {:?}", random_tuple.2);
println!("3 : {:?}", random_tuple.3);
println!("4 : {:?}", random_tuple.4);
println!("5 : {:?}", random_tuple.5);
}
여기서 재밌는 점은, Vector의 경우 같은 type의 요소들만 가질 수 있으나 다음과 같이 여러개의 타입을 묶어서 사용할 수도 있음
fn main(){
let my_vec = vec![("hey",9), ("Hello there", 123123)];
println!("{:?}", my_vec)
}
Destructuring! -> js의 분해구조할당과 비슷
fn main(){
let str_tuple = ("one", "two", "three");
let (a,b,c) = str_tuple;
println!("Item 'a' is : {}", a);
}
array 도 똑같이 분해 가능!
fn main(){
let str_array = ["one", "two", "three"];
let [a,_,_] = str_array; // 관심없는 b, c 대신 _ 사용 가능 -> 워닝 안뜸
println!("Item 'a' is : {}", a);
}
흐름제어
다른언어에서 if 문을 사용할 때 조건은 () 안에 넣는데 러스트는 괄호를 쓸 필요 없음 (에러는 아님)
fn main(){
let my_number = 5;
if my_number == 7 {
println!("It's seven");
} else if my_number == 6 {
println!("It's six");
} else {
println!("It's a different number");
}
}
&& || 도 동일하게 사용 가능
fn main(){
let my_number = 5;
if my_number == 5 && my_number == 11 {
println!("Both are matched");
} else if my_number == 5 || my_number == 11 {
println!("my number is 5 or 11");
} else {
println!("It's a different number");
}
}
하지만 이것보다 더 자주 쓰이는건 "match"
-> switch 와 비슷
fn main(){
let my_number: u8 = 5;
match my_number{
0 => println!("It's a zero"),
1 => println!("It's a one")
}
} //=>에러남. u8 은 256까지 가능한데 나머지에 대한 정의가 안돼있기 때문
fn main(){
let my_number: u8 = 5;
match my_number{
0 => println!("It's a zero"),
1 => println!("It's a one"),
_ => println!("Other number"); // _ 기호를 사용해서 나머지 타입(else)에 대한 정의
}
}
match 로 변수에 값을 할당할 수도 있음
fn main(){
let my_number: u8 = 5;
let my_second_number = match my_number{
0 => 23,
1 => 34,
_ => 0
};
println!("{}", my_second_number);
}
tuple 활용
여러개의 변수를 한번에 비교할 수도 있음!
fn main(){
let sky = "cloudy";
let temperature = "warm";
match (sky, temperature){
("cloudy", "cold") => println!("It's not very nice day"),
("cloudy", "warm") => println!("It's a nice day"),
("cloudy", _) => println!("Cloudy and something else"),
_ => println!("Not sure what the weather is")
}
}
조건문도 사용 가능
fn main(){
let children = 5;
let married = true;
match(children, married){
(children, married) if married == false => println!("Not married with {} children", children),
(c,m) if c==0 && m => println!("Married but with no children"),
_ => println!("Some other type of marriage and children combination")
}
}