lazy_static은 이미 유행이 지났다!?once_벨을 사용하세요.
이 문장을 세 줄로 요약하면
lazy_static
lazy_static
의 대체품once_cell
으로 등장Rust의 글로벌 변수에는 많은 제한이 있습니다.
Rust에 글로벌 변수가 있음
unsafe
이런 제한이 있어서 사용하기 매우 어려운 물건이다.
예를 들어 커다란 텍스트를 한 번만 읽고 전역 변수에 저장하려고 합니다.
그러나 이렇게 쓰면
unsafe
없으면 전역 변수를 변경할 수 없어 컴파일 오류가 발생합니다.static mut LARGE_TEXT : String = String::new();
fn main() {
LARGE_TEXT = load_large_text();
}
/// 巨大なテキストを読み込む
fn load_large_text() -> String {
todo!()
}
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
--> src\main.rs:3:3
|
3 | LARGE_TEXT = load_large_text();
| ^^^^^^^^^^ use of mutable static
|
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
unsafe
를 사용하면 컴파일 오류가 사라지지만 커다란 텍스트를 사용할 때 실수로 다시 쓸 수 있어 위험합니다.static mut LARGE_TEXT: String = String::new();
fn main() {
unsafe {
// 今LARGE_TEXTを使用していないとは限らない、その事をどうか思い出して頂きたい
LARGE_TEXT = load_large_text();
}
}
중 RefCell
를 사용하면 실행 시 사용 여부를 확인하고 안전하다고 판단되면 RefCell
라인이 안전하지 않아 사용할 수 없습니다.use std::cell::RefCell;
static LARGE_TEXT: RefCell<String> = RefCell::new(String::new());
fn main() {
*LARGE_TEXT.borrow_mut() = load_large_text();
}
error[E0277]: `std::cell::RefCell<std::string::String>` cannot be shared between threads safely
--> src\main.rs:2:1
|
2 | static LARGE_TEXT: RefCell<String> = RefCell::new(String::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::RefCell<std::string::String>` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<std::string::String>`
= note: shared static variables must have a type that implements `Sync`
그렇다면RefCell
의 라인 안전판Mutex
이라면 전역 변수가 상수 이외에서 초기화되지 않아 사용할 수 없습니다.use std::sync::Mutex;
static LARGE_TEXT: Mutex<String> = Mutex::new(String::new());
fn main() {
*LARGE_TEXT.lock().unwrap() = load_large_text();
}
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
--> src\main.rs:2:36
|
2 | static LARGE_TEXT: Mutex<String> = Mutex::new(String::new());
|
"Rust의 전역 변수는 사용할 수 없습니다!"그렇게 생각하는 네가 정답이다.
전역 변수를 직접 사용하지 말고 더 쉽게 사용할 수 있는 크레인을 사용하세요.
제한을 없애면 전역 변수의 크레인을 사용하기 쉽다static
lazy_static
를 사용하면 첫 방문할 때 초기화 처리를 한 번만 수행하는 전역 변수를 만들 수 있습니다.use lazy_static::lazy_static;
lazy_static! {
static ref LARGE_TEXT: String = load_large_text();
}
fn main() {
println!("{}", *LARGE_TEXT);
}
lazy_static
는 매우 편리하여 곧 공장 표준의 지위에 올랐다.그런데 이거
lazy_static
는 매크로를 사용했기 때문에 이해하기 어렵지 않나요?lazy_static의 대체 once셀이 등장합니다.
이 가운데
lazy_static
와 같은 처리를 구현한 매크로 없음once_cell
이 등장했다.방금
lazy_static
의 예로once_cell
를 사용하면 다음과 같다.use once_cell::sync::Lazy;
static LARGE_TEXT: Lazy<String> = Lazy::new(|| load_large_text());
fn main() {
println!("{}", *LARGE_TEXT);
}
매크로를 사용하지 않았기 때문에 이 변수를 함수나 구조 구성원에게 전달할 수도 있습니다.fn may_use_large_text(large_text: &Lazy<String>) {
todo!()
}
struct LargeTextCache {
large_text: Lazy<String>,
}
다운로드 수는 아직 lazy_static
에 미치지 못했지만 급속히 증가하고 있다표준 라이브러리 가입도 고려.Links
lazy_static
once_cell
Reference
이 문제에 관하여(lazy_static은 이미 유행이 지났다!?once_벨을 사용하세요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/frozenlib/articles/lazy_static_to_once_cell텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)