Last active
October 1, 2023 12:30
-
-
Save knuu/d809dac1390bb473b277cadb71b52721 to your computer and use it in GitHub Desktop.
rust 本 5 章
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::{collections::HashMap, vec}; | |
type Table = HashMap<String, Vec<String>>; | |
fn show(table: &Table) { | |
for (artist, works) in table { | |
println!("works by {}:", artist); | |
for work in works { | |
println!(" {}", work); | |
} | |
} | |
} | |
fn sort_works(table: &mut Table) { | |
for (_artist, works) in table { | |
works.sort(); | |
} | |
} | |
fn fn_5_1() { | |
let mut table = Table::new(); | |
table.insert( | |
"Gesualdo".to_string(), | |
vec![ | |
"many madrigals".to_string(), | |
"Tenebrae Responsoria".to_string(), | |
], | |
); | |
table.insert( | |
"Caravaggio".to_string(), | |
vec![ | |
"The Musicians".to_string(), | |
"The Calling of St. Matthew".to_string(), | |
], | |
); | |
table.insert( | |
"Cellini".to_string(), | |
vec![ | |
"Perseus with the head of Medusa".to_string(), | |
"a salt cellar".to_string(), | |
], | |
); | |
show(&table); | |
assert_eq!(table["Gesualdo"][0], "many madrigals"); | |
sort_works(&mut table); | |
show(&table); | |
} | |
fn mut_ref() { | |
let mut x = 10; | |
let r1 = &mut x; | |
println!("{}", r1); | |
// let r2 = &x; | |
// println!("{} {}", r1, r2); | |
} | |
fn mut_ref2() { | |
let mut x = 10; | |
let r1 = &mut x; | |
println!("{}", r1); | |
let r2 = &x; | |
println!("{}", r2); | |
} | |
fn fn_5_2_1() { | |
// 5.2.1 | |
// 参照は明示的に & 演算子で明示的に作成し, | |
// 参照解決も * 演算子で明示的に行う | |
// 共有参照での例 | |
let x = 10; | |
let r = &x; | |
assert!(*r == 10); | |
// 共変参照での例 | |
let mut y = 32; | |
let m = &mut y; | |
*m += 32; | |
assert!(*m == 64); | |
let r; | |
{ | |
let x = 5; | |
r = &x; | |
println!("r: {}", r); | |
} | |
} | |
struct S522 { | |
a: i32, | |
} | |
fn dot_implicit(s: &S522) { | |
assert!(s.a == 10); | |
assert!((*s).a == 10); | |
} | |
fn fn_5_2_1_2() { | |
let s = S522 { a: 10 }; | |
dot_implicit(&s); | |
let mut v = vec![1973, 1968]; | |
v.sort(); | |
(&mut v).sort(); | |
} | |
fn fn_5_2_2(b: bool) { | |
let x = 10; | |
let y = 20; | |
let mut r = &x; | |
if b { | |
r = &y; | |
} | |
assert!(*r == 10 || *r == 20); | |
} | |
fn fn_5_2_3() { | |
struct S { | |
x: i32, | |
} | |
let s = S { x: 729 }; | |
let r = &s; | |
let rr = &r; | |
let rrr = &rr; | |
// .演算子は参照を複数段階たどって解決してくれる | |
assert_eq!(r.x, 729); | |
assert_eq!(rr.x, 729); | |
assert_eq!(rrr.x, 729); | |
} | |
fn fn_5_2_4() { | |
let x = 10; | |
let y = 10; | |
let rx = &x; | |
let ry = &y; | |
let rrx = ℞ | |
let rry = &ry; | |
// 参照先を自動的にたどって比較してくれる | |
assert!(rx == ry); | |
assert!(rrx == rry); | |
assert!(!std::ptr::eq(rx, ry)); | |
assert!(!std::ptr::eq(rrx, rry)); | |
// 比較は両辺の型が一致する必要がある | |
// assert!(rx == rrx); // NG | |
assert!(rx == *rrx); // OK | |
assert!(x == **rrx); // OK | |
} | |
fn fn_5_2_5() { | |
let x: Option<&i32> = None; | |
// let x = None; // Option<i32> を明示しないと NG | |
assert_eq!(x, None); | |
} | |
fn factorial(n: usize) -> usize { | |
(1..n + 1).product() | |
} | |
fn fn_5_2_6_ok() { | |
let r = &factorial(6); | |
assert_eq!(r + &1009, 1729); | |
assert_eq!(*r + 1009, 1729); | |
assert_eq!(r + &1009, 1729); | |
// OK | |
assert_eq!(&factorial(6) + &1009, 1729); | |
} | |
fn fn_5_2_6_ng() { | |
// NG | |
// let r; | |
// r = &factorial(6); | |
// assert_eq!(r + &1009, 1729); | |
} | |
fn fn_5_2_6_ng2() { | |
// NG | |
// let a = 0; | |
// let r; | |
// r = &(720 + a); | |
// assert_eq!(r + &1009, 1729); | |
} | |
fn fn_5_2_6_ok2() { | |
// NG | |
// let r; | |
// r = &(&720 + &0); | |
// assert_eq!(r + &1009, 1729); | |
} | |
// ======================================== | |
// 5.3.1 | |
// ======================================== | |
fn fn_5_3_1_ng() { | |
// let r; | |
// { | |
// let x = 1; | |
// r = &x; | |
// } | |
// assert_eq!(*r, 1); | |
} | |
fn fn_5_3_1_ok() { | |
let r; | |
{ | |
let x = 1; | |
r = &x; | |
assert_eq!(*r, 1); | |
} | |
} | |
fn fn_5_3_1_ok2() { | |
let r; | |
let x; | |
{ | |
x = 1; | |
r = &x; | |
} | |
assert_eq!(*r, 1); | |
} | |
fn fn_5_3_1_ok3() { | |
let rr; | |
{ | |
let mut r = &10; | |
rr = &r; | |
assert_eq!(**rr, 10); | |
{ | |
let x = 1; | |
r = &x; | |
assert_eq!(*r, 1); | |
} | |
} | |
} | |
// ======================================== | |
// 5.3.2 | |
// ======================================== | |
// static mut STASH: &i32 = &128; | |
// fn f_5_3_2_ng(p: &i32) { | |
// unsafe { | |
// STASH = p; | |
// } | |
// } | |
static mut STASH: &i32 = &128; | |
// fn f_5_3_2_ng2<'a>(p: &'a i32) { | |
// unsafe { | |
// STASH = p; | |
// } | |
// } | |
fn f_5_3_2_ok<'a>(p: &'static i32) { | |
unsafe { | |
STASH = p; | |
} | |
} | |
// ======================================== | |
// 5.3.3 | |
// ======================================== | |
fn fn_5_3_3() { | |
// OK | |
static OOMOJI: i32 = 12345; | |
f_5_3_2_ok(&OOMOJI); | |
// NG: 生存期間が 'static より短いものは渡せない | |
// let komoji = 123456; | |
// f_5_3_2_ok(&komoji); | |
} | |
fn f_5_3_3_static<'a>(p: &'a i32) { | |
println!("{}", *p); | |
} | |
fn fn_5_3_3_2() { | |
// OK | |
let komoji = 123456; | |
f_5_3_3_static(&komoji); | |
// OK: 'a に対して 'static を渡すのは OK | |
static OOMOJI: i32 = 12345; | |
f_5_3_3_static(&OOMOJI); | |
} | |
fn fn_5_3_2_3() { | |
let r; | |
{ | |
let x = 1; | |
{ | |
let r2; | |
r2 = &x; | |
r = r2; | |
} | |
assert_eq!(*r, 1); | |
} | |
} | |
// ======================================== | |
// 5.3.4 | |
// ======================================== | |
fn smallest(v: &[i32]) -> &i32 { | |
let mut s = &v[0]; | |
for r in &v[1..] { | |
if *r < *s { | |
s = r; | |
} | |
} | |
s | |
} | |
fn fn_5_3_4_ng() { | |
let s; | |
{ | |
let parabola = [9, 4, 1, 0, 1, 4, 9]; | |
s = smallest(¶bola); | |
} | |
// assert_eq!(*s, 0); | |
} | |
fn fn_5_3_4_ok() { | |
let s; | |
{ | |
let parabola = [9, 4, 1, 0, 1, 4, 9]; | |
s = smallest(¶bola); | |
assert_eq!(*s, 0); | |
} | |
} | |
fn smallest2(v: &[i32]) -> i32 { | |
let mut s = v[0]; | |
for r in &v[1..] { | |
if *r < s { | |
s = *r; | |
} | |
} | |
s | |
} | |
fn fn_5_3_4_2() { | |
let s; | |
{ | |
let parabola = [9, 4, 1, 0, 1, 4, 9]; | |
s = smallest2(¶bola); | |
} | |
assert_eq!(s, 0); | |
} | |
// ======================================== | |
// 5.3.5 | |
// ======================================== | |
/* | |
struct S535Ng { | |
r: &i32, | |
} | |
// */ | |
struct S535Ok<'a> { | |
r: &'a i32, | |
} | |
struct S535Static { | |
r: &'static i32, | |
} | |
/*/ | |
fn fn_5_3_5_ng() { | |
let s; | |
{ | |
let r = 10; | |
s = S535Ok { r: &r }; | |
} | |
println!("{}", s.r); | |
} | |
// */ | |
fn fn_5_3_5_ok() { | |
let s; | |
{ | |
let r = 10; | |
s = S535Ok { r: &r }; | |
println!("{}", s.r); | |
} | |
} | |
/* | |
struct D_Ng { | |
s: S535Ok, | |
} | |
// */ | |
struct D_Ok<'a> { | |
s: S535Ok<'a>, | |
} | |
struct D_OkStatic { | |
s: S535Ok<'static>, | |
} | |
struct D_OkStatic2 { | |
s: S535Static, | |
} | |
// ======================================== | |
// 5.3.6 | |
// ======================================== | |
fn return_x_same<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { | |
x | |
} | |
/*/ | |
fn fn_5_3_6_fn_ng() { | |
let x = 1; | |
let r; | |
{ | |
let y = 2; | |
r = return_x_same(&x, &y); | |
} | |
println!("{}", r); | |
} | |
// */ | |
fn return_x_notsame<'a, 'b>(x: &'a i32, y: &'b i32) -> &'a i32 { | |
x | |
} | |
fn fn_5_3_6_fn_ok() { | |
let x = 1; | |
let r; | |
{ | |
let y = 2; | |
r = return_x_notsame(&x, &y); | |
} | |
println!("{}", r); | |
} | |
struct S536Same<'a> { | |
x: &'a i32, | |
y: &'a i32, | |
} | |
/* | |
fn fn_5_3_6_struct_ng() { | |
let x = 10; | |
let r; | |
{ | |
let y = 20; | |
let s = S536Same { x: &x, y: &y }; | |
r = s.x; | |
} | |
println!("{}", r); | |
} | |
// */ | |
struct S536NotSame<'a, 'b> { | |
x: &'a i32, | |
y: &'b i32, | |
} | |
fn fn_5_3_6_struct_ok() { | |
let x = 10; | |
let r; | |
{ | |
let y = 20; | |
let s = S536NotSame { x: &x, y: &y }; | |
r = s.x; | |
} | |
println!("{}", r); | |
} | |
// ======================================== | |
// 5.3.7 | |
// ======================================== | |
/* | |
fn longest_ng<'a, 'b>(x: &'a str, y: &'b str) -> &str { | |
if x.len() > y.len() { | |
x | |
} else { | |
y | |
} | |
} | |
// */ | |
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { | |
if x.len() > y.len() { | |
x | |
} else { | |
y | |
} | |
} | |
// ======================================== | |
// 5.4.1 | |
// ======================================== | |
/* | |
fn fn_share_then_change_ng() { | |
let mut v = vec![1, 2, 3]; | |
let r = &v; | |
v = vec![100, 200, 300]; | |
println!("{}", r[0]); | |
} | |
fn fn_share_then_move_ng() { | |
let v = vec![1, 2, 3]; | |
let r = &v; | |
let aside = v; | |
println!("{}", r[0]); | |
} | |
// */ | |
fn fn_share_then_change_ok() { | |
let mut v = vec![1, 2, 3]; | |
let r = &v; | |
println!("{}", r[0]); | |
v = vec![100, 200, 300]; | |
} | |
fn fn_share_then_move_ok() { | |
let v = vec![1, 2, 3]; | |
let r = &v; | |
println!("{}", r[0]); | |
let aside = v; | |
} | |
/* | |
fn fn_share_then_assign_ng() { | |
let mut v = vec![1, 2, 3]; | |
let r = &v; | |
v[0] = 100; | |
println!("{}", r[0]); | |
} | |
fn fn_share_then_push_ng() { | |
let mut v = vec![1, 2, 3]; | |
let r = &v; | |
v.push(100); | |
println!("{}", r[0]); | |
} | |
// */ | |
/* | |
fn fn_mutref_access_ng() { | |
let mut t = (1, 2); | |
let r = &mut t; | |
t; | |
println!("{:?}", r); | |
} | |
fn fn_mutref_access_child_ng() { | |
let mut t = (1, 2); | |
let r = &mut t; | |
t.0; | |
println!("{:?}", r); | |
} | |
fn fn_mutref_access_parent_ng() { | |
let mut t = ((1, 2), (3, 4)); | |
let r = &mut t.0; | |
t; | |
println!("{:?}", r); | |
} | |
// */ | |
fn fn_sharedref_reref() { | |
let mut t = (1, 2); | |
let r = &mut t; | |
let r0 = &r.0; | |
let r1 = &mut r.1; | |
println!("{} {}", r0, r1); | |
} | |
/* | |
fn fn_5_4_1() { | |
let mut x = 10; | |
let r1 = &x; | |
let r2 = &x; | |
x += 10; | |
let m = &mut x; | |
println!("{} {} {}", r1, r2, m); | |
} | |
// */ | |
/* | |
fn fn_5_4_2() { | |
let mut y = 10; | |
let m1 = &mut y; | |
let m2 = &mut y; | |
let z = y; | |
println!("{} {} {}", m1, m2, z); | |
} | |
// */ | |
fn fn_5_4_3() { | |
let mut y = 10; | |
let m1 = &y; | |
let m2 = &y; | |
let z = y; | |
println!("{} {} {}", m1, m2, z); | |
} | |
struct ImportantExcerpt<'a> { | |
part: &'a str, | |
} | |
fn fn_tmp2() { | |
// 僕をイシュマエルとお呼び。何年か前・・・ | |
let novel = String::from("Call me Ishmael. Some years ago..."); | |
// "'.'が見つかりませんでした" | |
let first_sentence = novel.split('.').next().expect("Could not find a '.'"); | |
let i = ImportantExcerpt { | |
part: first_sentence, | |
}; | |
println!("{}", i.part); | |
} | |
fn fn_tmp3_ng() { | |
let mut data = vec![1, 2, 3]; | |
let x = &data[0]; | |
// data.push(4); // pub fn push(&mut self, value: T) なので,&mut self が必要 | |
println!("{}", x); | |
} | |
fn fn_tmp3_ok() { | |
let mut data = vec![1, 2, 3]; | |
let x = &data[0]; | |
println!("{}", x); | |
data.push(4); | |
} | |
#[derive(Debug)] | |
struct X<'a>(&'a i32); | |
// impl Drop for X<'_> { | |
// fn drop(&mut self) {} | |
// } | |
fn fn_tmp3_ng2() { | |
let mut data = vec![1, 2, 3]; | |
let x = X(&data[0]); | |
println!("{:?}", x); | |
data.push(4); | |
} | |
#[derive(Debug)] | |
struct Foo; | |
impl Foo { | |
fn mutate_and_share(&mut self) -> &Foo { | |
&*self | |
} | |
fn share(&self) {} | |
} | |
fn fn_tmp4_ng() { | |
let mut foo = Foo; | |
let loan = Foo::mutate_and_share(&mut foo); | |
Foo::share(&foo); | |
// println!("{:?}", loan); | |
} | |
// fn failed_borrow<'a>() { | |
// let _x = 12; | |
// // ERROR: `_x` does not live long enough | |
// let _y: &'a i32 = &_x; | |
// // Attempting to use the lifetime `'a` as an explicit type annotation | |
// // inside the function will fail because the lifetime of `&_x` is shorter | |
// // than that of `y`. A short lifetime cannot be coerced into a longer one. | |
// } | |
// fn as_str(data: &u32) -> &str { | |
// let s: &'static String = &format!("{}", data); | |
// s | |
// } | |
// fn smallest(v: &[i32]) -> &i32 { | |
// let mut s = &v[0]; | |
// for r in &v[1..] { | |
// if *r < *s { | |
// s = r; | |
// } | |
// } | |
// s | |
// } | |
// struct StringTable { | |
// elements: Vec<String>, | |
// } | |
// impl StringTable { | |
// fn find_by_prefix(&self, prefix: &str) -> Option<&String> { | |
// for i in 0..self.elements.len() { | |
// if self.elements[i].starts_with(prefix) { | |
// return Some(&self.elements[i]); | |
// } | |
// } | |
// None | |
// } | |
// } | |
// fn extend(vec: &mut Vec<f64>, slice: &[f64]) { | |
// for elt in slice { | |
// vec.push(*elt); | |
// } | |
// } | |
fn main() { | |
fn_5_1(); | |
mut_ref(); | |
mut_ref2(); | |
fn_5_2_1(); | |
fn_5_2_1_2(); | |
fn_5_2_2(true); | |
fn_5_2_2(false); | |
fn_5_2_3(); | |
fn_5_2_4(); | |
fn_5_2_5(); | |
fn_5_2_6_ok(); | |
fn_5_2_6_ng(); | |
fn_5_3_1_ng(); | |
fn_5_3_1_ok(); | |
fn_5_3_1_ok2(); | |
fn_5_3_1_ok3(); | |
f_5_3_2_ok(&126); | |
fn_5_3_2_3(); | |
fn_5_3_3(); | |
fn_5_3_3_2(); | |
fn_5_3_4_ng(); | |
fn_5_3_4_ok(); | |
fn_5_3_4_2(); | |
fn_tmp2(); | |
fn_tmp3_ng(); | |
fn_tmp3_ok(); | |
fn_5_3_1_ok2(); | |
fn_5_4_3(); | |
fn_5_3_5_ok(); | |
// fn_share_then_change_ng(); | |
// let a = vec![2, 1, 3]; | |
// println!("{:?}", a); | |
// println!("{}", smallest(&a)); | |
// { | |
// let s; | |
// let parabola = [9, 4, 1, 0, 1, 4, 9]; | |
// s = smallest(¶bola); | |
// assert_eq!(*s, 0); | |
// } | |
// struct S<'a> { | |
// r: &'a i32, | |
// } | |
// let s; | |
// { | |
// let x = 10; | |
// s = S { r: &x }; | |
// assert_eq!(*s.r, 10); | |
// } | |
// assert_eq!(*s.r, 10); | |
// struct D<'a> { | |
// s: S<'a>, | |
// } | |
// struct D { | |
// s: S<'static>, | |
// } | |
// struct S<'a> { | |
// x: &'a i32, | |
// y: &'a i32, | |
// } | |
// struct S<'a, 'b> { | |
// x: &'a i32, | |
// y: &'b i32, | |
// } | |
// let x = 10; | |
// let r; | |
// { | |
// let y = 20; | |
// { | |
// let s = S { x: &x, y: &y }; | |
// r = s.x; | |
// } | |
// } | |
// println!("{}", r); | |
// let v = vec![1, 2, 3]; | |
// let r = &v; | |
// // println!("{:?}", r); | |
// let aside = v; | |
// // println!("{:?}", r); | |
// let mut wave = Vec::new(); | |
// let head = vec![0.0, 1.0]; | |
// let tail = [0.0, -1.0]; | |
// extend(&mut wave, &head); | |
// extend(&mut wave, &tail); | |
// assert_eq!(wave, vec![0.0, 1.0, 0.0, -1.0]); | |
// extend(&mut wave, &wave); | |
// assert_eq!(wave, vec![0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment