453 lines
20 KiB
Text
453 lines
20 KiB
Text
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Interior Mutability"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"use std::collections::HashMap;\n",
|
|
"\n",
|
|
"struct DnsService {\n",
|
|
" lookup_table: HashMap<String, String>\n",
|
|
"}\n",
|
|
"\n",
|
|
"impl DnsService {\n",
|
|
" fn lookup(&self, hostname: &str) -> Option<&str> {\n",
|
|
" self.lookup_table.get(hostname).map(|s| s.as_str())\n",
|
|
" }\n",
|
|
"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Some(\"1.22.33.1\")\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"let dns_service = DnsService {\n",
|
|
" lookup_table: [(\"www.example.com\".to_string(), \"143.33.44.4\".to_string()),\n",
|
|
" (\"www.rust-lang.org\".to_string(), \"1.22.33.1\".to_string()),\n",
|
|
" (\"www.mozilla.org\".to_string(), \"2.43.44.3\".to_string())\n",
|
|
" ].iter().cloned().collect()\n",
|
|
"};\n",
|
|
"\n",
|
|
"println!(\"{:?}\", dns_service.lookup(\"www.rust-lang.org\"));"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "Error",
|
|
"evalue": "cannot assign to `self.counter`, which is behind a `&` reference",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[31m[E0594] Error:\u001b[0m cannot assign to `self.counter`, which is behind a `&` reference",
|
|
" \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0m command_4:1:1 \u001b[38;5;246m]\u001b[0m",
|
|
" \u001b[38;5;246m│\u001b[0m",
|
|
" \u001b[38;5;246m 9 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mk\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m&\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mh\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mm\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m&\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m-\u001b[0m\u001b[38;5;249m>\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mO\u001b[0m\u001b[38;5;249mp\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m<\u001b[0m\u001b[38;5;249m&\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249m>\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m{\u001b[0m",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;100m│\u001b[0m ",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m help: consider changing this to be a mutable reference: `mut `",
|
|
" \u001b[38;5;246m10 │\u001b[0m \u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54ms\u001b[0m\u001b[38;5;54me\u001b[0m\u001b[38;5;54ml\u001b[0m\u001b[38;5;54mf\u001b[0m\u001b[38;5;54m.\u001b[0m\u001b[38;5;54mc\u001b[0m\u001b[38;5;54mo\u001b[0m\u001b[38;5;54mu\u001b[0m\u001b[38;5;54mn\u001b[0m\u001b[38;5;54mt\u001b[0m\u001b[38;5;54me\u001b[0m\u001b[38;5;54mr\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m+\u001b[0m\u001b[38;5;54m=\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m1\u001b[0m\u001b[38;5;249m;\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m/\u001b[0m\u001b[38;5;249m/\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mE\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249m:\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m`\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249m`\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mb\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249ma\u001b[0m\u001b[38;5;249mu\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mb\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mw\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249md\u001b[0m",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m ",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m `self` is a `&` reference, so the data it refers to cannot be written",
|
|
"\u001b[38;5;246m────╯\u001b[0m"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"use std::collections::HashMap;\n",
|
|
"\n",
|
|
"struct DnsService {\n",
|
|
" lookup_table: HashMap<String, String>,\n",
|
|
" counter: i32\n",
|
|
"}\n",
|
|
"\n",
|
|
"impl DnsService {\n",
|
|
" fn lookup(&self, hostname: &str) -> Option<&str> {\n",
|
|
" self.counter += 1; // Error: cannot assign to `self.counter` because it is borrowed\n",
|
|
" self.lookup_table.get(hostname).map(|s| s.as_str())\n",
|
|
" }\n",
|
|
"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## `Cell` - for `Copy` types"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"use std::collections::HashMap;\n",
|
|
"use std::cell::Cell;\n",
|
|
"\n",
|
|
"struct DnsService {\n",
|
|
" lookup_table: HashMap<String, String>,\n",
|
|
" counter: Cell<i32>\n",
|
|
"}\n",
|
|
"\n",
|
|
"impl DnsService {\n",
|
|
" fn lookup(&self, hostname: &str) -> Option<&str> {\n",
|
|
" let value = self.counter.get();\n",
|
|
" self.counter.set(value + 1);\n",
|
|
" self.lookup_table.get(hostname).map(|s| s.as_str())\n",
|
|
" }\n",
|
|
"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"The type of the variable dns_service was redefined, so was lost.\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Some(\"1.22.33.1\")\n",
|
|
"Some(\"143.33.44.4\")\n",
|
|
"None\n",
|
|
"Dns used 3 times\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"let dns_service = DnsService {\n",
|
|
" lookup_table: [(\"www.example.com\".to_string(), \"143.33.44.4\".to_string()),\n",
|
|
" (\"www.rust-lang.org\".to_string(), \"1.22.33.1\".to_string()),\n",
|
|
" (\"www.mozilla.org\".to_string(), \"2.43.44.3\".to_string())\n",
|
|
" ].iter().cloned().collect(), \n",
|
|
" counter: Cell::new(0)\n",
|
|
"};\n",
|
|
"\n",
|
|
"println!(\"{:?}\", dns_service.lookup(\"www.rust-lang.org\"));\n",
|
|
"println!(\"{:?}\", dns_service.lookup(\"www.example.com\"));\n",
|
|
"println!(\"{:?}\", dns_service.lookup(\"www.infotraining.pl\"));\n",
|
|
"\n",
|
|
"println!(\"Dns used {} times\", dns_service.counter.get());"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## RefCell - for non-`Copy` types"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"use std::collections::HashMap;\n",
|
|
"use std::cell::RefCell;\n",
|
|
"\n",
|
|
"type LookupLog = Vec<String>;\n",
|
|
"\n",
|
|
"struct DnsService {\n",
|
|
" lookup_table: HashMap<String, String>,\n",
|
|
" lookup_log: RefCell<LookupLog>,\n",
|
|
"}\n",
|
|
"\n",
|
|
"impl DnsService {\n",
|
|
" fn lookup(&self, hostname: &str) -> Option<&str> {\n",
|
|
" self.lookup_log.borrow_mut().push(hostname.to_string());\n",
|
|
" self.lookup_table.get(hostname).map(|s| s.as_str())\n",
|
|
" }\n",
|
|
"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Some(\"1.22.33.1\")\n",
|
|
"Some(\"143.33.44.4\")\n",
|
|
"None\n",
|
|
"Dns looked up for [\"www.rust-lang.org\", \"www.example.com\", \"www.infotraining.pl\"]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"let dns_service = DnsService {\n",
|
|
" lookup_table: [(\"www.example.com\".to_string(), \"143.33.44.4\".to_string()),\n",
|
|
" (\"www.rust-lang.org\".to_string(), \"1.22.33.1\".to_string()),\n",
|
|
" (\"www.mozilla.org\".to_string(), \"2.43.44.3\".to_string())\n",
|
|
" ].iter().cloned().collect(), \n",
|
|
" lookup_log: RefCell::new(Vec::new())\n",
|
|
"};\n",
|
|
"\n",
|
|
"println!(\"{:?}\", dns_service.lookup(\"www.rust-lang.org\"));\n",
|
|
"println!(\"{:?}\", dns_service.lookup(\"www.example.com\"));\n",
|
|
"println!(\"{:?}\", dns_service.lookup(\"www.infotraining.pl\"));\n",
|
|
"\n",
|
|
"println!(\"Dns looked up for {:?}\", dns_service.lookup_log.borrow());"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## RwLock - for thread-safe shared access"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"use std::collections::HashMap;\n",
|
|
"use std::cell::RefCell;\n",
|
|
"\n",
|
|
"type LookupLog = Vec<String>;\n",
|
|
"\n",
|
|
"struct DnsService {\n",
|
|
" lookup_table: HashMap<String, String>,\n",
|
|
" lookup_log: RefCell<LookupLog>,\n",
|
|
"}\n",
|
|
"\n",
|
|
"impl DnsService {\n",
|
|
" fn from_slice(data: &[(&str, &str)]) -> DnsService {\n",
|
|
" DnsService {\n",
|
|
" lookup_table: data.iter().cloned().map(|(k, v)| (k.to_string(), v.to_string())).collect(),\n",
|
|
" lookup_log: RefCell::new(Vec::new())\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" fn lookup(&self, hostname: &str) -> Option<&str> {\n",
|
|
" self.lookup_log.borrow_mut().push(hostname.to_string());\n",
|
|
" self.lookup_table.get(hostname).map(|s| s.as_str())\n",
|
|
" }\n",
|
|
"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "Error",
|
|
"evalue": "`RefCell<Vec<String>>` cannot be shared between threads safely",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[31m[E0277] Error:\u001b[0m `RefCell<Vec<String>>` cannot be shared between threads safely",
|
|
" \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0m command_11:1:1 \u001b[38;5;246m]\u001b[0m",
|
|
" \u001b[38;5;246m│\u001b[0m",
|
|
" \u001b[38;5;246m6 │\u001b[0m \u001b[38;5;54m╭\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m▶\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mh\u001b[0m\u001b[38;5;249md\u001b[0m\u001b[38;5;249m_\u001b[0m\u001b[38;5;249m1\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;100ms\u001b[0m\u001b[38;5;100mt\u001b[0m\u001b[38;5;100md\u001b[0m\u001b[38;5;100m:\u001b[0m\u001b[38;5;100m:\u001b[0m\u001b[38;5;100mt\u001b[0m\u001b[38;5;100mh\u001b[0m\u001b[38;5;100mr\u001b[0m\u001b[38;5;100me\u001b[0m\u001b[38;5;100ma\u001b[0m\u001b[38;5;100md\u001b[0m\u001b[38;5;100m:\u001b[0m\u001b[38;5;100m:\u001b[0m\u001b[38;5;100ms\u001b[0m\u001b[38;5;100mp\u001b[0m\u001b[38;5;100ma\u001b[0m\u001b[38;5;100mw\u001b[0m\u001b[38;5;100mn\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;68m|\u001b[0m\u001b[38;5;68m|\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m{\u001b[0m",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m│\u001b[0m \u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m┬\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m \u001b[38;5;68m─\u001b[0m\u001b[38;5;68m┬\u001b[0m ",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m│\u001b[0m \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m required by a bound introduced by this call",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m│\u001b[0m \u001b[38;5;68m│\u001b[0m ",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m│\u001b[0m \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m note: required because it's used within this closure",
|
|
" \u001b[38;5;240m ┆\u001b[0m \u001b[38;5;54m┆\u001b[0m ",
|
|
" \u001b[38;5;246m8 │\u001b[0m \u001b[38;5;54m├\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m▶\u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m \u001b[0m\u001b[38;5;54m}\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m│\u001b[0m ",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m `RefCell<Vec<String>>` cannot be shared between threads safely",
|
|
" \u001b[38;5;240m │\u001b[0m ",
|
|
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;115mNote\u001b[0m: note: required because it appears within the type `DnsService`",
|
|
"\u001b[38;5;246m───╯\u001b[0m"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"fn main() {\n",
|
|
" let dns_service = DnsService::from_slice(&[(\"www.example.com\", \"122.33.22.33\"), (\"www.rust-lang.org\", \"1.2.3.4\"), (\"www.mozilla.org\", \"9.4.3.4\")]);\n",
|
|
"\n",
|
|
" println!(\"{:?}\", dns_service.lookup(\"www.rust-lang.org\"));\n",
|
|
"\n",
|
|
" let thd_1 = std::thread::spawn(|| {\n",
|
|
" println!(\"{:?}\", dns_service.lookup(\"www.example.com\"));\n",
|
|
" });\n",
|
|
"\n",
|
|
" thd_1.join().unwrap();\n",
|
|
"}\n",
|
|
"\n",
|
|
"main();"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Arc + RwLock - for shared access across threads"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"use std::collections::HashMap;\n",
|
|
"use std::sync::RwLock;\n",
|
|
"use std::borrow::BorrowMut;\n",
|
|
"\n",
|
|
"type LookupLog = Vec<String>;\n",
|
|
"\n",
|
|
"struct DnsService {\n",
|
|
" lookup_table: HashMap<String, String>,\n",
|
|
" lookup_log: RwLock<LookupLog>,\n",
|
|
"}\n",
|
|
"\n",
|
|
"impl DnsService {\n",
|
|
" fn from_slice(data: &[(&str, &str)]) -> DnsService {\n",
|
|
" DnsService {\n",
|
|
" lookup_table: data.iter().cloned().map(|(k, v)| (k.to_string(), v.to_string())).collect(),\n",
|
|
" lookup_log: RwLock::new(Vec::new())\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" fn lookup(&self, hostname: &str) -> Option<&str> {\n",
|
|
" let mut log = self.lookup_log.write().unwrap();\n",
|
|
" log.push(hostname.to_string());\n",
|
|
" self.lookup_table.get(hostname).map(|s| s.as_str())\n",
|
|
" }\n",
|
|
"}"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "rust"
|
|
}
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Some(\"1.2.3.4\")\n",
|
|
"Some(\"122.33.22.33\")\n",
|
|
"Some(\"9.4.3.4\")\n",
|
|
"Dns looked up for [\"www.rust-lang.org\", \"www.example.com\", \"www.mozilla.org\"]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"use std::sync::Arc;\n",
|
|
"\n",
|
|
"fn main() {\n",
|
|
" let dns_service = Arc::new(\n",
|
|
" DnsService::from_slice(&[(\"www.example.com\", \"122.33.22.33\"), (\"www.rust-lang.org\", \"1.2.3.4\"), (\"www.mozilla.org\", \"9.4.3.4\")])\n",
|
|
" );\n",
|
|
"\n",
|
|
" println!(\"{:?}\", dns_service.lookup(\"www.rust-lang.org\"));\n",
|
|
"\n",
|
|
" let mut dns = dns_service.clone();\n",
|
|
" let thd_1 = std::thread::spawn(move || {\n",
|
|
" println!(\"{:?}\", dns.lookup(\"www.example.com\"));\n",
|
|
" });\n",
|
|
"\n",
|
|
" let mut dns = dns_service.clone();\n",
|
|
" let thd_2 = std::thread::spawn(move || {\n",
|
|
" println!(\"{:?}\", dns.lookup(\"www.mozilla.org\"));\n",
|
|
" });\n",
|
|
"\n",
|
|
" thd_1.join().unwrap();\n",
|
|
" thd_2.join().unwrap();\n",
|
|
"\n",
|
|
" println!(\"Dns looked up for {:?}\", dns_service.lookup_log.read().unwrap());\n",
|
|
"}\n",
|
|
"\n",
|
|
"main();"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Rust",
|
|
"language": "rust",
|
|
"name": "rust"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": "rust",
|
|
"file_extension": ".rs",
|
|
"mimetype": "text/rust",
|
|
"name": "Rust",
|
|
"pygment_lexer": "rust",
|
|
"version": ""
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|