Rust100本ノックより: ライブラリの作り方(追い出し編)

準備編では、内包するライブラリクレートの作り方を出してくれてました。今度はライブラリクレートに実際のコードから移していきます。

大元のコード

大元のコードとして、No.005を使ってみます。

コードはこんな感じが初期状態になります。

use std::io::{self, Write};

fn get_number_with_prompt(prompt: &str) -> i32 {
   print!("{}", &prompt);
   io::stdout().flush().ok();
   let mut input = String::new();
   io::stdin().read_line(&mut input).ok();
   let input = input.trim();
   let value: i32 = input.parse().unwrap();
   value
}

fn main() {
   let num1: i32 = get_number_with_prompt("input 1st number: ");
   let num2: i32 = get_number_with_prompt("input 2nd number: ");
   println!("和: {}", num1+num2);
   println!("差: {}", num1-num2);
   println!("積: {}", num1*num2);
   if num2 != 0 {
       println!("商: {}, 余り: {}", num1/num2 , num1 % num2);
   } else {
       println!("ゼロ除算を行おうとしています");
   }

}

get_number_with_prompt()が以降の問題で使うことになるコードです。引数は問い合わせの際にコンソールに出したい文字列(&str: スタック上の文字列部分の借用)となります。文字列を出して入力を促し、入力された文字列を数値に変換して返すものとなっています。

これをコピペ(カット&ペースト)を使って、ライブラリ側に移動させてしまいます。


// mylib/src/lib.rs内
fn get_number_with_prompt(prompt: &str) -> i32 {
   print!("{}", &prompt);
   io::stdout().flush().ok();
   let mut input = String::new();
   io::stdin().read_line(&mut input).ok();
   let input = input.trim();
   let value: i32 = input.parse().unwrap();
   value
}

すると、それぞれで異常が検知されます。VScode(RLS)様々です。

画像1

画像2

波線を頑張って消します。No.005のコードにおいては、ライブラリの利用を宣言しておきます。

use std::io::{self, Write};
extern crate mylib;  // extern crate でプロジェクトから直接見えてないものを取り込む

fn main() {
...
}

そしてlib.rsについては、シンボルioがわからないと言うことでエラーでしたので、No.005のソースにあるuse文を移設しましょう。

画像5

まだ消えないね

でも、これでもまだ波線が消えません。消えない理由は2つでてます。

- No.005側: get_number_with_prompt()がスコープ上で見えてない
- ライブラリ側(lib.rs): get_number_with_prompt()が使われてない(ように見える)

関数はextern crateで外部指定で取り込んでるmylib空間に存在するので、mylib::としてあげないとね。

画像3

差し替えたら差し替えたで、今度は「その関数privateだし」という感じです。Rustでの関数はprivateの扱いになっており、同じソースの中(語弊アリ)でしか使えません。ということで公開状態(public)にしておかないといけませんね。

画像4

と、ライブラリ側でpub宣言を加え、公開状態にしておきます。ライブラリの中で参照するようなものはそのままプライベート状態にすれば良いでしょう。外に見せられるものは最小限にしておいた方がトラブル少なくなって良いと思います。こう言うのをきちんとメッセージで教えてくれるので、エラーは友達です!

これで両者から波線も消えたことでしょう(適宜保存をお忘れ無く)。残りのソースも同様に書き換えて対応できるでしょうから、いじっていきましょうかね。

なお、ソース中にmylib::を加えまくるのは面倒かもしれませんから、お好みでuse文でシンボルを取り込んでおくと良いですね。

画像6


この記事が気に入ったらサポートをしてみませんか?