Rust, 쉽게 하자!

Rust 입문

[Rust] Cell

바로크냥 2022. 10. 22. 06:36

5. Cell

Cell 타입은 mut 키워드를 사용하지 않아도 저장한 값을 변경할 수 있습니다. Cell 타입은 마치 물건 하나만 넣을 수 있는 상자와 같습니다. 이미 들어 있는 값을 꺼내서 사용하고 다른 값을 넣어 줄 수도 있고, 이미 들어 있는 값을 그냥 지우고 다른 값을 넣어 줄 수도 있습니다.

코드를 보면서 확인 해 보겠습니다.

 

use std::cell::Cell;   

fn main(){
    let c = Cell::new(10);       // 1
    println!("{:?}", c);
    let c1 = c.replace(5);        // 2
    println!("{}", c1);
    println!("{:?}", c);
    c.set(100);                   // 3
    println!("{:?}", c);
    println!("{}", c.get());          // 5
    println!("{}", c.into_inner());    // 4
}

// 출력
Cell { value: 10 }
10
Cell { value: 5 }
Cell { value: 100 }
100
100

//1: Cell::new(10)은 새로운 Cell 타입을 만듭니다.

여기에서는 10을 값으로 넣었습니다. 출력해 보면 변수가 가지고 있는 값을 확인할 수 있습니다.

Cell { value: 10 }

// 2: replace 메소드는 Cell에 들어 있는 값을 꺼내서 반환하고 다른 값을 집어넣습니다.

위 예에서도 Cell에서 꺼낸 값을 저장한 c1 변수는 값 10을 가지고 있습니다.

그리고 Cell은 대체된 값 5를 가지고 있습니다.

// 3: set 메소드는 이미 들어 있던 값을 지우고 다른 값을 집어넣습니다.

위 코드에서도 원래 있던 값은 사라지고 새로운 값 100이 들어 갔습니다.

// 4: into_inner() 메서드는 Cell 안에 들어 있는 값을 꺼내서 돌려줍니다. i

nto_inner() 메서드를 사용해서 값을 꺼내면 Cell에는 아무런 값이 남아 있지 않고, 값이 없으므로 변수도 지워집니다.

빈 배열이 가능한 배열이나 벡터와는 다르게 Cell은 빈 Cell을 만들 수 없습니다. 반드시 어떤 값을 가져야 합니다.

// 5: 만약 안에 들어 있는 값을 꺼내서 사용하고 값도 계속 유지하고 싶다면 get() 메소드를 사용합니다.

get() 메서드에는 into_inner() 메서드와 달리 Copy 트레이트가 구현되어 있습니다.

다음 코드를 보면, c.into_inner() 메서드로 변수 c의 값을 꺼내서 사용하고 다시 변수 c를 출력했습니다.

결과는 에러가 납니다. 에러 메시지를 보면, Copy 트레이트가 구현되어 있지 않다고 알려 줍니다.

그래서 변수 c는 소유권을 잃고 지워집니다.

 println!("{}", c.into_inner());
 println!("{:?}", c);

// 출력
'''에러
4   |     let c = Cell::new(10);
    |         - move occurs because `c` has type `Cell<i32>`, which does not implement the `Copy` trait

Cell 타입 변수를 처음 만들었을 때 저장한 값의 타입을 다른 타입으로 바꿀 수 없습니다.

  let x = Cell::new(String::from("hello"));  // 1
    x.set(10);                               // 2

// 출력
''에러
19 |     x.set(10);
   |           ^^- help: try using a conversion method: `.to_string()`
   |           |
   |           expected struct `String`, found integer

// 1: 변수 x는 String 타입 값을 담고 있습니다.

// 2: 그런데 다시 set() 메소드로 정수 10을 넣었습니다. 

// 출력: 에러가 납니다. 에러 메시지를 보면 String 타입이 와야 하는데 정수가 들어 있다고 알려 줍니다.

그리고 친절하게도 tostring() 메소드로 정수 10을 String 타입으로 바꾸는 방법까지 추천하고 있습니다.

 

 
반응형

'Rust 입문' 카테고리의 다른 글

[Rust] 동시성  (0) 2022.10.24
[Rust] RefCell 그리고 Arc, Mutex  (0) 2022.10.23
[Rust] Rc와 Weak  (0) 2022.10.21
[Rust] Vec  (0) 2022.10.19
[Rust] Box  (0) 2022.10.15