Home [Rust] Struct std::vec::Vec 정리
Post
Cancel
Preview Image

[Rust] Struct std::vec::Vec 정리

오늘은 rustlings 의 exercices에서 collections에 있는 vec 문제를 통해서

간단히 Struct std::vec::Vec 을 정리해보겠다.

생성

먼저 다음은 vec1.rs 문제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
    let a = [10, 20, 30, 40]; // a plain array
    let v = // TODO: declare your vector here with the macro for vectors

    (a, v)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_array_and_vec_similarity() {
        let (a, v) = array_and_vec();
        assert_eq!(a, v[..]);
    }
}

아래 테스트에서 확인할 수 있듯이, 주어진 array a 와 같게 vector v 를 정의하면 된다.

방법 1. Vec::new()를 통해서 생성한 뒤 push() 메소드를 사용한다.

먼저 기본적인 방법은 vector를 생성한 뒤, element를 하나씩 push해주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
    let a = [10, 20, 30, 40]; // a plain array
    // new() 를 통해서 생성해준다.
    // push 되어야 하므로 let mut으로 해준다.
    let mut v = Vec::new();
    v.push(10);
    v.push(20);
    v.push(30);
    v.push(40);

    (a, v)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_array_and_vec_similarity() {
        let (a, v) = array_and_vec();
        assert_eq!(a, v[..]);
    }
}

먼저 let mut v = Vec::new();를 통해서 vector를 생성해준다.

안에 생성 시, 안에 변수가 들어가야 하므로, let mut 으로 해야한다.

만약 let v = Vec::new();를 한 뒤 아래 push 를 하게 되면 다음의 에러가 발생한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
⚠️  Compiling of exercises/collections/vec1.rs failed! Please try again. Here's the output:
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
  --> exercises/collections/vec1.rs:24:5
   |
23 |     let v = Vec::new();
   |         - help: consider changing this to be mutable: `mut v`
24 |     v.push(10);
   |     ^ cannot borrow as mutable

error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
  --> exercises/collections/vec1.rs:25:5
   |
23 |     let v = Vec::new();
   |         - help: consider changing this to be mutable: `mut v`
24 |     v.push(10);
25 |     v.push(20);
   |     ^ cannot borrow as mutable

error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
  --> exercises/collections/vec1.rs:26:5
   |
23 |     let v = Vec::new();
   |         - help: consider changing this to be mutable: `mut v`
...
26 |     v.push(30);
   |     ^ cannot borrow as mutable

error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
  --> exercises/collections/vec1.rs:27:5
   |
23 |     let v = Vec::new();
   |         - help: consider changing this to be mutable: `mut v`
...
27 |     v.push(40);
   |     ^ cannot borrow as mutable

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0596`.

보시다시피 mutable 로 바꾸는걸 고려하라고 해준다.

방법 2. vec![] macro 를 사용한다.

다음 방법은 macro를 통해서 생성하는 방법이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
    let a = [10, 20, 30, 40]; // a plain array
    let v = vec![10, 20, 30, 40];

    (a, v)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_array_and_vec_similarity() {
        let (a, v) = array_and_vec();
        assert_eq!(a, v[..]);
    }
}

이 방법을 통해서 argument 를 포함한 Vec를 생성해준다.

따로 수정이 없으므로, mut가 필요없다는 것을 볼 수 있다.

방법 3. <[_]>.to_vec() 를 이용한다.

다음 방법은 slice의 to_vec() 함수를 통해서 생성해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
    let a = [10, 20, 30, 40]; // a plain array
    let v = a.to_vec();

    (a, v)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_array_and_vec_similarity() {
        let (a, v) = array_and_vec();
        assert_eq!(a, v[..]);
    }
}

이 방법을 통해서 array a 를 바로 vector로 변환시켜줄 수 있다.

Vec의 iter_mut

다음은 vec2.rs 문제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// vec2.rs
// A Vec of even numbers is given. Your task is to complete the loop
// so that each number in the Vec is multiplied by 2.
//
// Make me pass the test!
//
// Execute the command `rustlings hint collections2` if you need
// hints.

// I AM NOT DONE

fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
    for i in v.iter_mut() {
        // TODO: Fill this up so that each element in the Vec `v` is
        // multiplied by 2.
    }

    // At this point, `v` should be equal to [4, 8, 12, 16, 20].
    v
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_vec_loop() {
        let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
        let ans = vec_loop(v.clone());

        assert_eq!(
            ans,
            v.iter()
                .map(|x| x * 2)
                .collect::<Vec<i32>>()
        );
    }
}

아래 테스트에서 보다시피,

let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();를 통해서

[2, 4, 6, 8, 10]v에 할당한 뒤,

vec_loop 함수를 통해서 [4, 8, 12, 16, 20]를 만들어줘야 하며,

1
2
3
4
for i in v.iter_mut() {
    // TODO: Fill this up so that each element in the Vec `v` is
    // multiplied by 2.
}

이 안에서 완성시키면 된다.

해답은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
    for i in v.iter_mut() {
        *i *= 2;
    }

    v
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_vec_loop() {
        let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
        let ans = vec_loop(v.clone());

        assert_eq!(
            ans,
            v.iter()
                .map(|x| x * 2)
                .collect::<Vec<i32>>()
        );
    }
}
1
2
3
for i in v.iter_mut() {
    *i *= 2;
}

이 부분 처럼 각 i 마다 2배한 것을 할당해주면 된다.

정리

위의 간단한 예제를 통해서 RustStruct std::vec::Vec에 대해서 간단히 알아봤다.

간단한 생성부터, iter_mul 예제뿐이지만, 예제에서 작성해야하는 코드 외에

테스트 코드를 보면서 더 깊이 공부할 수 있었다.

References

rustlings

array

Vec

Solution

This post is licensed under CC BY 4.0 by the author.

[영화] 나는 내일, 어제의 너와 만난다

[Netflix] 에놀라 홈즈 반 토막 후기