如何使用锈中弱引用的向量

问题描述

我想保留对象数组以在发生某些事件时回调。我不需要拥有这些对象,并且在对象被重新分配的情况下很好,我可以从容器中延迟地删除侦听器。

从概念上讲,类似这样,但是会出现很多编译/所有权错误

trait EventListener {
  fn event_occured(&mut self,event_name: String); 
}

struct Listener {
  listeners : Vec<Weak<EventListener>>
}

impl Listener {
   fn observe_event(&mut self,listener: impl EventListener) {
      self.listeners.push(Weak(listener)); // how can i Box the listener in a weak container
   }
   fn listen_for_events() {

      ... did something here and figured it should broadcast to all listeners ... 
      for listener in self.listeners {
          if listener.is_alive { listener.event_occured(event)} ;  // how to check the weak ref is valid?
      }
   }
}

解决方法

所有者需要与该代码协作,以允许其保留弱引用。这意味着Listener::observe_event需要采用Weak<dyn EventListener>Rc<dyn EventListener>。 (或Arc等价物),目前它取一个EventListener值,当Listener::observe_event返回时,当然会释放该值。

,

这是一个基于您发布的代码(在playground上)的功能示例:

<ipython-input-10-3786d79ff26a> in <module>
----> 1 from pygmo import *
      2 from pygmo import *
      3 import numpy as np
      4 pop_size=200
      5 problems=[1,2]

~\Anaconda3\lib\site-packages\pygmo\__init__.py in <module>
     11 from ._version import __version__
     12 # We import the sub-modules into the root namespace
---> 13 from .core import *
     14 from .core import _pagmo_version_major,_pagmo_version_minor,_pagmo_version_patch
     15 from .plotting import *

ImportError: DLL load failed: The specified procedure could not be found.```

它打印

use std::rc::{Rc,Weak};

trait EventListener {
  fn event_occured(&self,event_name: &String); 
}

struct Listener {
  listeners : Vec<Weak<dyn EventListener>>
}

impl Listener {
   fn observe_event(&mut self,listener: &Rc<dyn EventListener>) {
      self.listeners.push(Rc::downgrade(listener));
   }
   
   fn listen_for_events(&self) {
        let event = String::new();
        for listener in &self.listeners {
            if let Some(strong_listener) = listener.upgrade() {
                strong_listener.event_occured(&event);
            }
        }
    }
}

struct A {}
impl EventListener for A {
    fn event_occured(&self,_event_name: &String) {
        println!("A");
    }
}

struct B {}
impl EventListener for B {
    fn event_occured(&self,_event_name: &String) {
        println!("B");
    }
}

fn main() {
    let a: Rc<dyn EventListener> = Rc::new(A{});
    let b: Rc<dyn EventListener> = Rc::new(B{});
    
    let mut listener = Listener { listeners: vec![] };
    
    listener.observe_event(&a);
    listener.observe_event(&b);
    
    listener.listen_for_events();
    
    // B goes out of scope
    drop(b);
    
    listener.listen_for_events();
}

似乎您对何时可以使用A B A 感到困惑。到目前为止,什么都没有释放,这不是 一种机制。仅与Weak配对时有效。