In order to challenge myself to learn Rust I'm trying to write something reasonably complex: an MNIST classifier. There are tons of variables holding references to other variables so it seems like a good candidate to understand lifetimes... well, I don't.
Here is a minimal example where I'm just trying to build a simple Network
structure:
struct Connection<'a> {
weight: f32,
neuron: &'a Neuron<'a>,
}
struct Neuron<'a> {
bias: Option<f32>,
inputs: Vec<Connection<'a>>,
}
struct Layer<'a> {
neurons: Vec<Neuron<'a>>,
}
struct Network<'a> {
layers: Vec<Layer<'a>>,
}
impl <'a> Network<'a> {
pub fn new() -> Network<'a> {
Network {
layers: Vec::new(),
}
}
pub fn add_layer(
&'a mut self,
neurons_count: usize,
) -> &'a mut Network<'a> {
let mut layer = Layer {
neurons: Vec::new(),
};
for _ in 0..neurons_count {
let neuron = Neuron {
bias: None,
inputs: Vec::new(),
};
layer.neurons.push(neuron);
}
if let Some(previous_layer) = self.layers.last_mut() {
for neuron in &mut layer.neurons {
for previous_neuron in &previous_layer.neurons {
let connection = Connection {
weight: 0.0,
neuron: &previous_neuron,
};
neuron.inputs.push(connection);
}
}
}
self.layers.push(layer); // cannot borrow `self.layers` as mutable more than once at a time
self // cannot borrow `*self` as mutable more than once at a time
}
}
pub fn create_network<'a>() -> Network<'a> {
let mut network = Network::new();
network
.add_layer(2)
.add_layer(2)
.add_layer(1)
;
network // cannot return value referencing local variable `network`
}
And here is a link to the corresponding playground.
In the add_layer
method, I do not understand how I can release the borrow that happens on line 41 such that the self.layers.push(layer)
is valid.
Same problem at line 60 in create_network
.
Am I approaching the issue in a totally wrong way, or am I just missing something completely obvious?