러스트 표준 라이브러리에 collections 라는 데이터 구조가 많이 포함되어 있다.
컬렉션에는 여러 값이 포함될 수 있고, 데이터들은 힙에 저장된다. 즉 컴파일 시간에 데이터의 양을 알 필요가 없으며 프로그램이 실행됨에 따라 증가하거나 축소될 수 있다.
러스트에서 자주 사용하는 3가지 컬렉션에 대해 알아보자.
- vector
- string
- hash map
위 세 가지 컬렉션 종류 외에 다른 종류를 알고 싶다면 여기를 참고하자.
Vector
Vec<T>, 백터(vector)는 메모리의 양 옆에 둘 이상의 (같은 타입의 단일 데이터 구조) 값을 저장할 수 있는 컬렉션 타입이다.
1. 백터 만들기
let v: Vec<i32> = Vec::new();
새로운 백터를 만들고 싶다면 Vec::new 함수를 호출한다.
※백터는 제너릭이기 때문에 들어갈 값의 타입(<i32>)을 미리 알려줘야 한다.
백터를 선언할 때 초기값을 갖는 경우에는 vec! 매크로를 사용한다.
let v = vec![1, 2, 3];
위 v 백터의 타입은 무엇을까? 정답은 i32이다.
enum SpreadsheetCell {
Int(i32),
Float(f64),
Text(String),
}
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Text(String::from("blue")),
SpreadsheetCell::Float(10.12),
];
위처럼 열거형을 사용하여 백터를 만들 수도 있다. 백터는 같은 유형을 가진 값만 저장할 수 있지만, enum은 다른 타입을 가진 열거형이더라도 동일한 enum 타입으로 간주하므로 해당 enum을 갖는 백터를 생성할 수 있게 된다.
2. 백터 수정/해제하기
let mut v = Vec::new();
v.push(5);
v.push(6);
v.push(7);
v.push(8);
벡터에 값을 추가하고 싶다면 push 메소드를 이용한다.
백터의 값을 바꾸고 싶다면 mut 키워드를 이용해 변경 가능하도록 만들어야 한다는 점을 잊지 말자.
구조체처럼, 백터는 스코프를 나가면 메모리에서 해제되고, 해제되면서 백터 안의 값들도 다 사라진다.
{
let v = vec![1, 2, 3, 4];
// do stuff with v
} // <- v goes out of scope and is freed here
3. 백터 읽기
백터 내의 값을 읽고 싶다면 2가지 방법이 있다.
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("The third element is {}", third); //3
match v.get(2) {
Some(third) => println!("The third element is {}", third), //3
None => println!("There is no third element."),
}
첫 번째 방법은 백터의 인덱스([]) 안의 값을 참조(&)해서 읽는 방법이다.
두 번째 방법은 get메소드를 사용하여 인덱스를 argument로 받아 처리하는 방법이다.
fn main() {
let v = vec![1, 2, 3, 4, 5];
let does_not_exist = &v[100];
}
첫 번째 방법으로 초과 인덱스를 실행한 경우
다음과 같은 에러가 발생하고,
두 번째 방법으로 초과 인덱스를 실행한 경우
fn main() {
let v = vec![1, 2, 3, 4, 5];
let _does_not_exist = v.get(100);
}
에러가 나지 않는다.
또한, 백터 참조 시 백터의 값이 참조되는 동안에는 백터에 변경이 일어나는 경우에는 에러가 발생할 수 있다.
fn main() {
let mut v = vec![1, 2, 3, 4, 5];
let first = &v[0];
v.push(6);
println!("The first element is: {}", first);
}
백터의 값을 반복하려는 경우 다음과 같이 for문을 사용할 수 있다.
let v = vec![100, 32, 57];
for i in &v {
println!("{}", i);
}
모든 요소를 변경하기 위해 변경 가능한 벡터의 각 요소에 대해 변경 가능한 참조를 이용할 수도 있다.
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
}
참조하는 값을 변경하려면 역참조 연산자(*)를 사용하여 값을 가져와야 한다.
백터에 대해 더 자세히 알고 싶다면 API 문서를 참고하자.
'러스트' 카테고리의 다른 글
공통 컬렉션(Common Collection) - 해쉬 맵 (0) | 2022.03.15 |
---|---|
공통 컬렉션(Common Collection) - 스트링 (0) | 2022.03.14 |
패키지, 크레이트, 모듈(2) (0) | 2022.03.12 |
패키지, 크레이트, 모듈(1) (0) | 2022.03.11 |
열거형과 Match (0) | 2022.03.11 |