저는 대부분 OOP 언어에서 왔기 때문에이 개념이 Rust에서 작동하도록하는 것은 다소 어렵습니다. 해당 유형으로 만든 "인스턴스"수를 계산하는 기본 카운터를 구현하고 나중에 사용할 수 있도록 벡터에 보관하고 싶습니다.
처음에는 정적 벡터 변수를 만드는 것이 여러 가지 시도했지만 소멸자가있는 정적 항목을 허용하지 않기 때문에 불가능했습니다.
이것이 나의 첫 번째 시도였습니다.
struct Entity {
name: String,
}
struct EntityCounter {
count: i64,
}
impl Entity {
pub fn init() {
let counter = EntityCounter { count: 0 };
}
pub fn new(name: String) {
println!("Entity named {} was made.", name);
counter += 1; // counter variable unaccessable (is there a way to make it global to the struct (?..idek))
}
}
fn main() {
Entity::init();
Entity::new("Hello".to_string());
}
둘째:
struct Entity {
name: String,
counter: i32,
}
impl Entity {
pub fn new(self) {
println!("Entity named {} was made.", self.name);
self.counter = self.counter + 1;
}
}
fn main() {
Entity::new(Entity { name: "Test".to_string() });
}
그 어느 것도 작동하지 않았고, 나는 그러한 기능을 구현할 수있는 방법에 대한 몇 가지 개념을 시도하고있었습니다.
귀하의 문제는 귀하가 설명하는 것보다 다소 근본적인 것처럼 보입니다. 당신은 벽에 무엇이 붙어 있는지 확인하기 위해 일종의 코드를 던지고 있으며, 그것은 단순히 당신을 어디에도 가지 않을 것입니다. 계속하기 전에 Rust Book을 완전히 읽는 것이 좋습니다 . 이해가 안되는 내용이 있으면 물어보세요. 현재로서는 변수 범위 지정, 반환 유형, 인스턴스 생성 작동 방식, 정적 작동 방식 및 매개 변수 전달 방식을 이해하지 못하고 있음을 보여줍니다. 그것은 이해를 쌓기 위해 정말 흔들리는 기반입니다.
이 특별한 경우에는 의도적으로 간단하지 않은 것을 요구하고 있습니다. 카운터 와 인스턴스 벡터 를 원한다고 말합니다 . 카운터는 충분히 간단하지만 인스턴스의 벡터? Rust는 다른 언어처럼 쉽게 공유하는 것을 허용하지 않습니다. 따라서이를 수행하는 방법 은 실제로 이것을 사용하려는 목적 에 따라 크게 달라집니다 .
다음은 A는 매우 무언가에 거친 추측 어쩌면 당신이 원하는 것을 막연하게 유사합니다.
/*!
Because we need the `lazy_static` crate, you need to add the following to your
`Cargo.toml` file:
```cargo
[dependencies]
lazy_static = "0.2.1"
```
*/
#[macro_use] extern crate lazy_static;
mod entity {
use std::sync::{Arc, Weak, Mutex};
use std::sync::atomic;
pub struct Entity {
pub name: String,
}
impl Entity {
pub fn new(name: String) -> Arc<Self> {
println!("Entity named {} was made.", name);
let ent = Arc::new(Entity {
name: name,
});
bump_counter();
remember_instance(ent.clone());
ent
}
}
/*
The counter is simple enough, though I'm not clear on *why* you even want
it in the first place. You don't appear to be using it for anything...
*/
static COUNTER: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
fn bump_counter() {
// Add one using the most conservative ordering.
COUNTER.fetch_add(1, atomic::Ordering::SeqCst);
}
pub fn get_counter() -> usize {
COUNTER.load(atomic::Ordering::SeqCst)
}
/*
There are *multiple* ways of doing this part, and you simply haven't given
enough information on what it is you're trying to do. This is, at best,
a *very* rough guess.
`Mutex` lets us safely mutate the vector from any thread, and `Weak`
prevents `INSTANCES` from keeping every instance alive *forever*. I mean,
maybe you *want* that, but you didn't specify.
Note that I haven't written a "cleanup" function here to remove dead weak
references.
*/
lazy_static! {
static ref INSTANCES: Mutex<Vec<Weak<Entity>>> = Mutex::new(vec![]);
}
fn remember_instance(entity: Arc<Entity>) {
// Downgrade to a weak reference. Type constraint is just for clarity.
let entity: Weak<Entity> = Arc::downgrade(&entity);
INSTANCES
// Lock mutex
.lock().expect("INSTANCES mutex was poisoned")
// Push entity
.push(entity);
}
pub fn get_instances() -> Vec<Arc<Entity>> {
/*
This is about as inefficient as I could write this, but again, without
knowing your access patterns, I can't really do any better.
*/
INSTANCES
// Lock mutex
.lock().expect("INSTANCES mutex was poisoned")
// Get a borrowing iterator from the Vec.
.iter()
/*
Convert each `&Weak<Entity>` into a fresh `Arc<Entity>`. If we
couldn't (because the weak ref is dead), just drop that element.
*/
.filter_map(|weak_entity| weak_entity.upgrade())
// Collect into a new `Vec`.
.collect()
}
}
fn main() {
use entity::Entity;
let e0 = Entity::new("Entity 0".to_string());
println!("e0: {}", e0.name);
{
let e1 = Entity::new("Entity 1".to_string());
println!("e1: {}", e1.name);
/*
`e1` is dropped here, which should cause the underlying `Entity` to
stop existing, since there are no other "strong" references to it.
*/
}
let e2 = Entity::new("Entity 2".to_string());
println!("e2: {}", e2.name);
println!("Counter: {}", entity::get_counter());
println!("Instances:");
for ent in entity::get_instances() {
println!("- {}", ent.name);
}
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다