Rust는 ‘statically typed’ 언어로 런타임 비용 없이 컴파일 타임에 메모리 안전을 보장하여 런타임 버그를 방지한다. 그러나 때로는 동적 값을 사용해야 할 때가 있다1. 아래의 예제는 ‘전역 정적 객체’를 구현한 몇 가지 방법(트릭)을 보여준다2.
Declare lazily evaluated constant
use lazy_static::lazy_static;
use std::collections::HashMap;
lazy_static! {
static ref PRIVILEGES: HashMap<&'static str, Vec<&'static str>> = {
let mut map = HashMap::new();
map.insert("가나다", vec!["user", "admin"]);
map.insert("마바사", vec!["user"]);
map
};
}
fn show_access(name: &str) {
let access = PRIVILEGES.get(name);
println!("{}: {:?}", name, access);
}
fn main() {
let access = PRIVILEGES.get("가나다");
println!("가나다: {:?}", access);
show_access("마바사");
}
/* 실행결과
가나다: Some(["user", "admin"])
마바사: Some(["user"])
*/
Global static objects
/*
[dependencies]
lazy_static = "1.4.0"
*/
#[macro_use]
extern crate lazy_static;
use std::sync::Mutex;
lazy_static! {
static ref STATES: Mutex<Vec<i32>> = Mutex::new(vec![1, 2, 3]);
}
fn current_item() {
println!("Current Value - {:?}", STATES.lock().unwrap());
}
fn total_count() -> usize {
STATES.lock().unwrap().iter().filter(|&n| *n == *n).count()
}
fn print_item() {
for (k, v) in STATES.lock().unwrap().iter().enumerate() {
println!("Value : {} - {}", k, v);
}
}
fn add_item(item: i32) {
STATES.lock().unwrap().push(item);
}
fn main() {
println!("Start - STATES Count = {}", total_count());
current_item();
for x in 100..102 {
// 100, 101 or (in 100..=101)
add_item(x)
}
print_item();
println!("End - STATES Count = {}", total_count());
}
/* 실행 결과
Start - STATES Count = 3
Current Value - [1, 2, 3]
Value : 0 - 1
Value : 1 - 2
Value : 2 - 3
Value : 3 - 100
Value : 4 - 101
End - STATES Count = 5
*/
참고로 ‘Rust’에 대한 추가(struct, webapi, json, …) 예제는 DebugJO/HelloWorldSample/Rust에서 볼 수 있다.
Reference
- Dmitry Soshnikov, Rust notes: dynamic and global static objects
- rust-lang-nursery.github.io, global_static: Declare lazily evaluated constant