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 타입으로 바꾸는 방법까지 추천하고 있습니다.

 

 
반응형