ライフタイム
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
引数と返り値ともに同じライフタイムを持たせたい場合は寿樹のように書く。
これはresultをかっこの前に宣言してるのでライフタイムの影響でエラーになる。
fn smp_main2() { let string1 = String::from("long string is long"); let result; { let string2 = String::from("xyz"); result = longest(string1.as_str(), string2.as_str()); } println!("The longest string is {}", result); }
xにだけライフタイムを付与してもコンパイルには通る。
fn longest2<'a>(x: &'a str, y: &str) -> &'a str { x }
これは共通のライフタイムのものを返してないからエラーになる。
fn longest3<'a>(x: &str, y: &str) -> &'a str { let result = String::from("really long string"); result.as_str(); }
ジェネリックな型引数、トレイト境界、ライフタイムを指定した記法らしい。少ししか読めない(´・ω・`)
fn smp_main5() { use std::fmt::Display; fn longest_with_an_announcement<'a, T>(x: &'a str, y: &'a str, ann: T) -> &'a str where T: Display, { println!("Announcement! {}", ann); if x.len() > y.len() { x } else { y } } }
閑話休題
lib.rsの作成を今まで
nvim lib.rs
として作成していたが実は下記のように記載するらしい。 ライブラリプロジェクトという。
cargo new adder --lib
自動生成されたテストモジュールの中身。テストで使う?
#[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }
テスト
メソッドのテストは下記のようにできる。
#[derive(Debug)] struct Rectangle { width: u32, height: u32, } impl Rectangle { fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.height > other.height } } #[cfg(test)] mod tests { use super::*; #[test] fn larger_can_hold_smaller() { let larger = Rectangle { width: 8, height: 7, }; let smaller = Rectangle { width: 5, height: 1, }; assert!(larger.can_hold(&smaller)); } #[test] fn smaller_cannot_hold_larger() { let larger = Rectangle { width: 8, height: 7, }; let smaller = Rectangle { width: 5, height: 1, }; assert!(!smaller.can_hold(&larger)); } } fn main() {}
asser_eq!は値が等しいか比較する。
pub fn add_two(a: i32) -> i32 { a + 2 } -- omit #[test] fn it_adds_two() { assert_eq!(4, add_two(2)); }
ろぐ
https://github.com/jacoloves/lab/commit/ba05cc6019222427e954504a9f9b8dcdfc5711ed