trainings/Rust_2026/rust-bs-2026-09-14/notebooks/11_internal_mutability.ipynb

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
}