Skip to content

Instantly share code, notes, and snippets.

@knuu
Last active October 1, 2023 12:30
Show Gist options
  • Save knuu/d809dac1390bb473b277cadb71b52721 to your computer and use it in GitHub Desktop.
Save knuu/d809dac1390bb473b277cadb71b52721 to your computer and use it in GitHub Desktop.
rust 本 5 章
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 = &rx;
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(&parabola);
}
// assert_eq!(*s, 0);
}
fn fn_5_3_4_ok() {
let s;
{
let parabola = [9, 4, 1, 0, 1, 4, 9];
s = smallest(&parabola);
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(&parabola);
}
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(&parabola);
// 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