새 구조체 초기화 감지

마르크 몰 나르

저는 대부분 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() });
}

그 어느 것도 작동하지 않았고, 나는 그러한 기능을 구현할 수있는 방법에 대한 몇 가지 개념을 시도하고있었습니다.

DK.

귀하의 문제는 귀하가 설명하는 것보다 다소 근본적인 것처럼 보입니다. 당신은 벽에 무엇이 붙어 있는지 확인하기 위해 일종의 코드를 던지고 있으며, 그것은 단순히 당신을 어디에도 가지 않을 것입니다. 계속하기 전에 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] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

배열에서 초기화되지 않은 구조체 확인

분류에서Dev

초기화되지 않은 C ++ 구조체의 동작

분류에서Dev

새 개체를 초기화 할 때 StackOverflow

분류에서Dev

초기화 구조체 오류 : 'theGrid'가 초기화되지 않고 사용 중입니다.

분류에서Dev

구조체로 배열을 초기화하려면 구조체 이름을 지정해야하는 이유

분류에서Dev

C ++에서 구조체를 새로 만들고 초기화하려면 어떻게해야합니까?

분류에서Dev

C ++에서 구조체를 새로 만들고 초기화하려면 어떻게해야합니까?

분류에서Dev

초기화되지 않은 회원들과 구조체를 복사

분류에서Dev

accept () 호출이 sockaddr 구조체를 초기화하지 않습니다.

분류에서Dev

구조체 포인터와 지정된 초기화를 사용하여 C 구조체를 초기화하는 방법

분류에서Dev

새 객체가 초기화되었지만 찾기 후에는 콜백 메서드

분류에서Dev

생성자의 초기화 목록에서 새 객체를 초기화하고 참조 할 수 있습니까?

분류에서Dev

루프에서 새 개체를 만들 때 초기화되지 않은 멤버 변수가 초기화됩니다.

분류에서Dev

typedef 구조체 기본 초기화

분류에서Dev

이전을 덮어 쓰지 않고 서버-클라이언트 프로그램의 모든 연결에 대해 새 구조체를 초기화하려고합니다.

분류에서Dev

구체화 모달 함수가 초기화되지 않음

분류에서Dev

C ++ 구조체의 집계 / 지정 초기화 : 다른 필드를 직접 참조

분류에서Dev

{0}로 구조체 초기화

분류에서Dev

정적 구조체 초기화

분류에서Dev

구조체 제로 초기화 방법

분류에서Dev

구조체에서 std :: vector 초기화

분류에서Dev

malloc으로 구조체 초기화

분류에서Dev

Ruby : 구조체 대 초기화

분류에서Dev

구조체 포인터 초기화

분류에서Dev

C ++ const 구조체 초기화

분류에서Dev

구조체에서 배열 초기화

분류에서Dev

C의 구조체 초기화

분류에서Dev

구조체 요소 초기화

분류에서Dev

새로운 객체를 구조화하기위한 객체 분해

Related 관련 기사

  1. 1

    배열에서 초기화되지 않은 구조체 확인

  2. 2

    초기화되지 않은 C ++ 구조체의 동작

  3. 3

    새 개체를 초기화 할 때 StackOverflow

  4. 4

    초기화 구조체 오류 : 'theGrid'가 초기화되지 않고 사용 중입니다.

  5. 5

    구조체로 배열을 초기화하려면 구조체 이름을 지정해야하는 이유

  6. 6

    C ++에서 구조체를 새로 만들고 초기화하려면 어떻게해야합니까?

  7. 7

    C ++에서 구조체를 새로 만들고 초기화하려면 어떻게해야합니까?

  8. 8

    초기화되지 않은 회원들과 구조체를 복사

  9. 9

    accept () 호출이 sockaddr 구조체를 초기화하지 않습니다.

  10. 10

    구조체 포인터와 지정된 초기화를 사용하여 C 구조체를 초기화하는 방법

  11. 11

    새 객체가 초기화되었지만 찾기 후에는 콜백 메서드

  12. 12

    생성자의 초기화 목록에서 새 객체를 초기화하고 참조 할 수 있습니까?

  13. 13

    루프에서 새 개체를 만들 때 초기화되지 않은 멤버 변수가 초기화됩니다.

  14. 14

    typedef 구조체 기본 초기화

  15. 15

    이전을 덮어 쓰지 않고 서버-클라이언트 프로그램의 모든 연결에 대해 새 구조체를 초기화하려고합니다.

  16. 16

    구체화 모달 함수가 초기화되지 않음

  17. 17

    C ++ 구조체의 집계 / 지정 초기화 : 다른 필드를 직접 참조

  18. 18

    {0}로 구조체 초기화

  19. 19

    정적 구조체 초기화

  20. 20

    구조체 제로 초기화 방법

  21. 21

    구조체에서 std :: vector 초기화

  22. 22

    malloc으로 구조체 초기화

  23. 23

    Ruby : 구조체 대 초기화

  24. 24

    구조체 포인터 초기화

  25. 25

    C ++ const 구조체 초기화

  26. 26

    구조체에서 배열 초기화

  27. 27

    C의 구조체 초기화

  28. 28

    구조체 요소 초기화

  29. 29

    새로운 객체를 구조화하기위한 객체 분해

뜨겁다태그

보관