Paradigms of Rust for the Go developer

It’s a good time to be a coder with languages like Rust and Go at our disposal
func main() {
c := make(chan bool)
m := make(map[string]string)
go func() {
m["1"] = "a" // First conflicting access.
c <- true
}()
m["2"] = "b" // Second conflicting access.
<-c
for k, v := range m {
fmt.Println(k, v)
}
}
func main() {
c := make(chan bool)
m := make(map[string]string)
go func() {
m["1"] = "a" <-- this will always happen first
c <- true
}()
<-c // Reading from the channel here synchronizes mutation
m["2"] = "b" <-- this will always happen after
for k, v := range m {
fmt.Println(k, v)
}
}
use std::sync::mpsc::channel;
use std::collections::HashMap;
use std::thread;
fn main() {
let (c_tx, c_rx) = channel();
let mut m = HashMap::new();

thread::spawn(move || {
m.insert(“1”, “a”);
c_tx.send(true).unwrap();
});
m.insert(“2”, “b”);
c_rx.recv().unwrap();
for (k, v) in &m {
println!(“{}, {}”, k, v);
}
}
<anon>:14:5: 14:6 error: use of moved value: `m` [E0382]
<anon>:14 m.insert("2", "b");
^
<anon>:14:5: 14:6 help: see the detailed explanation for E0382
<anon>:9:19: 12:6 note: `m` moved into closure environment here because it has type `std::collections::hash::map::HashMap<&'static str, &'static str>`, which is non-copyable
<anon>: 9 thread::spawn(move || {
<anon>:10 m.insert("1", "a");
<anon>:11 c_tx.send(true).unwrap();
<anon>:12 });
<anon>:9:19: 12:6 help: perhaps you meant to use `clone()`?
<anon>:17:20: 17:21 error: use of moved value: `m` [E0382]
<anon>:17 for (k, v) in &m {
^
<anon>:17:20: 17:21 help: see the detailed explanation for E0382
<anon>:9:19: 12:6 note: `m` moved into closure environment here because it has type `std::collections::hash::map::HashMap<&'static str, &'static str>`, which is non-copyable
<anon>: 9 thread::spawn(move || {
<anon>:10 m.insert("1", "a");
<anon>:11 c_tx.send(true).unwrap();
<anon>:12 });
<anon>:9:19: 12:6 help: perhaps you meant to use `clone()`?
error: aborting due to 2 previous errors

Loaded question: so is Rust’s supremely verbose and almost story-like error messaging really more complicated or is trying to pin-point data-races in production due to an app exhibiting undefined behavior more complicated?

use std::sync::mpsc::channel;
use std::thread;
use std::collections::HashMap;
use std::sync::Arc;
fn main() {
let (tx, rx) = channel();
let mut m = HashMap::new();

m.insert(“a”, “1”);
m.insert(“b”, “2”);

let arc = Arc::new(m); // Tells Rust we're sharing state
for _ in 0..8 {
let tx = tx.clone();
let arc = arc.clone();
thread::spawn(move || {
let msg = format!(“Accessed {:?}”, arc);
tx.send(msg).unwrap();
});
}
drop(tx); // Effectively closes the channel for data in rx {
println!(“{:?}”, data);
}
}
use std::sync::mpsc::channel;
use std::collections::HashMap;
use std::thread;
use std::sync::{Arc, Mutex};
fn main() {
let (c_tx, c_rx) = channel();
let m = HashMap::new();

// Wrap m with a Mutex, wrap the mutex with Arc
let arc = Arc::new(Mutex::new(m));
let t_arc = arc.clone();
thread::spawn(move || {
let mut z = t_arc.lock().unwrap();
z.insert(“1”, “a”);
c_tx.send(true).unwrap();
});
// Extra scope is needed to avoid the deadlock
{
let mut x = arc.lock().unwrap();
x.insert(“2”, “b”);
}

c_rx.recv().unwrap();
for (k, v) in m.iter() {
println!(“{}, {}”, k, v);
}
}
<anon>:33:19: 33:20 error: use of moved value: `m` [E0382]
<anon>:33 for (k, v) in m.iter() {
^
<anon>:33:19: 33:20 help: see the detailed explanation for E0382
<anon>:11:35: 11:36 note: `m` moved here because it has type `std::collections::hash::map::HashMap<&'static str, &'static str>`, which is non-copyable
<anon>:11 let arc = Arc::new(Mutex::new(m));
^
error: aborting due to previous error
for (k, v) in m.iter() {
println!(“{}, {}”, k, v);
}
let a = arc.lock().unwrap();
for (k, v) in a.iter() {
println!(“{}, {}”, k, v);
}
use std::sync::mpsc::channel;
use std::collections::HashMap;
use std::thread;
use std::sync::{Arc, Mutex};
fn main() {
let (c_tx, c_rx) = channel();
let m = HashMap::new();
// Wrap m with a Mutex, wrap the mutex with Arc
let arc = Arc::new(Mutex::new(m));
let t_arc = arc.clone();
thread::spawn(move || {
let mut z = t_arc.lock().unwrap();
z.insert(“1”, “a”);
c_tx.send(true).unwrap();
});
// Extra scope is needed to avoid the deadlock
{
let mut x = arc.lock().unwrap();
x.insert(“2”, “b”);
}
c_rx.recv().unwrap(); let a = arc.lock().unwrap();
for (k, v) in a.iter() {
println!(“{}, {}”, k, v);
}
}

--

--

Ralph Caraveo was inspired so much by the Go language that he packed up his C#/.Net skills and never looked back.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store