Rust 특징

정명진·2023년 3월 9일
0

Rust 특징을 정리하는 글입니다.

계속 업데이트 할 예정입니다.

변수는 기본적으로 불변으로 관리한다. 하지만 mut을 추가해 가변성으로 사용가능하다.

Rust는 iterator를 한번밖에 못쓴다. 계속 쓰려면 계속 init이 필요하다.

아래는 실제 겪었던 문제다.

impl Solution {
    pub fn longest_common_prefix(strs: Vec<String>) -> String {
        let mut idx = 0;
        let base: &String = &strs[0];
        let mut baseLen = base.len();
        let str_iter = strs.iter();
        for i in 0..baseLen{
            let mut isSame = true;
            
            for str in str_iter {
                if idx >= str.len() || str.as_bytes()[idx] != base.as_bytes()[idx]{
                    isSame = false;
                    break;
                }
            }

            if isSame{
                idx = idx + 1;
            }else{
                break;
            }

        }
        
        return base[0..idx].to_string();
    }
}

그랬더니 아래와 같은 에러가 등장했다.

The compiler says:
v1_iter moved due to this implicit call to .into_iter()
help: consider borrowing to avoid moving into the for loop: &v1_iter

이는 rust에서 iterator는 한번만 사용이 가능해서이다. 그런데 하나의 iterator로 for문 안에서 계속 돌리니 발생한 에러였다.

impl Solution {
    pub fn longest_common_prefix(strs: Vec<String>) -> String {
        let mut idx = 0;
        let base: &String = &strs[0];
        let mut baseLen = base.len();
     
        for i in 0..baseLen{
            let mut isSame = true;
            let str_iter = strs.iter();
            for str in str_iter {
                if idx >= str.len() || str.as_bytes()[idx] != base.as_bytes()[idx]{
                    isSame = false;
                    break;
                }
            }

            if isSame{
                idx = idx + 1;
            }else{
                break;
            }

        }
        
        return base[0..idx].to_string();
    }
}

위와 같이 for안에 iter를 계속 init하면 해결된다.

rust indexing 하기

rust 패러다임에서 우리가 일반적으로 접근하는 인덱싱을 사용하면 작동하지 않는다...

우선 index 값이 usize 여야 하고...
그리고 string에 접근할때는 byte 배열로 변환후 char로 type casting이 필요하다.

use std::collections::BTreeMap;

impl Solution {
    
    pub fn restore_string(s: String, indices: Vec<i32>) -> String {
        let mut db = BTreeMap::new();
        let len = s.len() as i32;
        for i in 0..len{
            db.insert(indices[i as usize], s.as_bytes()[i as usize] as char);
        };
        let mut result = String::new();
        for key in db.keys(){
            result.push(*db.get(key).unwrap()); // &char to char
        };
        return result;
    }
}

rust Map getValue

rust에서 map을 사용하면서 get을 하면 Java Optional 처럼 값이 반환된다. 이때 unwrap 하면 레퍼런스 타입으로 반환이 된다. 이를 unreference해서 기본 primitive type으로 변환해야 한다.

rust 복사

기본적으로 rust에서 x, y 변수가 있을때 x를 y에 대입하면 x는 더이상 접근이 불가하다.
copy나 clone을 써서 해결가능, clone은 메모리로 관리 되는 애들까지 복사할때 사용
primitive는 copy로 해결 가능하다. shallow copy, deep copy로 이해하면 된다.

#[derive(Clone)]
struct Product{
    id: i32,
    name: String,
    description: String,
    image: String,
    price: f64,
}

&란 뭐지?

Rust는 기본적으로 메모리를 한번 쓰면 소유권이 넘어갔다고 생각하고 해당 scope에서 삭제해버린다. 즉 moved 소유권이 이전된 상태라 또 사용을 못한다는 문구를 본적이 있을것이다. 이때 이를 해결하려면 &로 사용하게끔 바꾸면 소유권이 넘어가지 않고 대여를 해준것이기 때문에 소유권을 가지고 있어서 재사용이 가능하다.

랜덤 바이트 생성하기

let randomValue = rand::thread_rng().gen::<[u8; 10]>();
println!("{:?}", randomValue);

할당된 사이즈의 배열에 값 넣기

let mut arr = [[0u8; 10]; 10];
    for i in 0..10{
        let start = 10 * i;
        let end = 10 * (i+1);
        arr[i].copy_from_slice(&resultArr[start..end]);
        println!("{:?}", arr[i]);
    }
profile
개발자로 입사했지만 정체성을 잃어가는중... 다시 준비 시작이다..

0개의 댓글