Rustlings をやってみた: functions 終了まで
前回のお話
functons1.rs
Debugging ⚠️ Compiling of exercises/functions/functions1.rs failed! Please try again. Here's the output:
error[E0425]: cannot find function `call_me` in this scope
--> exercises/functions/functions1.rs:7:5
|
7 | call_me();
| ^^^^^^^ not found in this scope
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.
当該の行のスコープからだと call_me();
の名前解決ができていないように見える.
というわけで,ソースコードを覗き見:
// functions1.rs
// Make me compile! Execute `rustlings hint functions1` for hints :)
// I AM NOT DONE
fn main() {
call_me();
}
既存の構造を壊さずに適当な関数を付け加えてアプローチしてみる:
// functions1.rs
// Make me compile! Execute `rustlings hint functions1` for hints :)
// I AM NOT DONE
fn call_me() {
}
fn main() {
call_me();
}
まずは空の関数を入れてみると...
🎉 🎉 The code is compiling! 🎉 🎉
Output:
====================
====================
You can keep working on this exercise,
or jump into the next one by removing the `I AM NOT DONE` comment:
2 | // Make me compile! Execute `rustlings hint functions1` for hints :)
3 |
4 | // I AM NOT DONE
5 |
6 | fn call_me() {
OK だった.特にスコープに関する細かい制約はないそうで,https://doc.rust-lang.org/book/ch03-03-how-functions-work.html を見ても前後関係は任意っぽい.
関数シグネチャの注釈の仕方とか Rust 独自の記法は後回し.
functons2.rs
Debugging ⚠️ Compiling of exercises/functions/functions2.rs failed! Please try again. Here's the output:
error: expected type, found `)`
--> exercises/functions/functions2.rs:10:16
|
10 | fn call_me(num:) {
| ^ expected type
error[E0425]: cannot find value `num` in this scope
--> exercises/functions/functions2.rs:11:17
|
11 | for i in 0..num {
| ^^^ not found in this scope
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0425`.
引数の型を期待するエラーと変数の名前解決のエラーが出ている.
を読むと,幾つかの重要な事実が書かれている:
- 関数の仮引数,実引数はそれぞれ parameter,argument と呼び分けられる
- 関数の引数シグネチャには型注釈が必要
というわけで,num
の型注釈は有無を言わせなさそう.とりあえず u8
で注釈したら通りました:
🎉 🎉 The code is compiling! 🎉 🎉
Output:
====================
Ring! Call number 1
Ring! Call number 2
Ring! Call number 3
====================
You can keep working on this exercise,
or jump into the next one by removing the `I AM NOT DONE` comment:
2 | // Make me compile! Execute `rustlings hint functions2` for hints :)
3 |
4 | // I AM NOT DONE
5 |
6 | fn main() {
こういう,別解の存在しない問題は好きです.
functons3.rs
Debugging ⚠️ Compiling of exercises/functions/functions3.rs failed! Please try again. Here's the output:
error[E0061]: this function takes 1 argument but 0 arguments were supplied
--> exercises/functions/functions3.rs:7:5
|
7 | call_me();
| ^^^^^^^-- supplied 0 arguments
| |
| expected 1 argument
|
note: function defined here
--> exercises/functions/functions3.rs:10:4
|
10 | fn call_me(num: u32) {
| ^^^^^^^ --------
error: aborting due to previous error
For more information about this error, try `rustc --explain E0061`.
関数シグネチャに合わない呼び出しを行っているだけ.なにか適当な u32
型の値を渡せば良さそう.100
を渡してみる.
🎉 🎉 The code is compiling! 🎉 🎉
Output:
====================
Ring! Call number 1
Ring! Call number 2
Ring! Call number 3
Ring! Call number 4
Ring! Call number 5
Ring! Call number 6
Ring! Call number 7
Ring! Call number 8
Ring! Call number 9
Ring! Call number 10
Ring! Call number 11
Ring! Call number 12
Ring! Call number 13
Ring! Call number 14
Ring! Call number 15
Ring! Call number 16
Ring! Call number 17
Ring! Call number 18
Ring! Call number 19
Ring! Call number 20
Ring! Call number 21
Ring! Call number 22
Ring! Call number 23
Ring! Call number 24
Ring! Call number 25
Ring! Call number 26
Ring! Call number 27
Ring! Call number 28
Ring! Call number 29
Ring! Call number 30
Ring! Call number 31
Ring! Call number 32
Ring! Call number 33
Ring! Call number 34
Ring! Call number 35
Ring! Call number 36
Ring! Call number 37
Ring! Call number 38
Ring! Call number 39
Ring! Call number 40
Ring! Call number 41
Ring! Call number 42
Ring! Call number 43
Ring! Call number 44
Ring! Call number 45
Ring! Call number 46
Ring! Call number 47
Ring! Call number 48
Ring! Call number 49
Ring! Call number 50
Ring! Call number 51
Ring! Call number 52
Ring! Call number 53
Ring! Call number 54
Ring! Call number 55
Ring! Call number 56
Ring! Call number 57
Ring! Call number 58
Ring! Call number 59
Ring! Call number 60
Ring! Call number 61
Ring! Call number 62
Ring! Call number 63
Ring! Call number 64
Ring! Call number 65
Ring! Call number 66
Ring! Call number 67
Ring! Call number 68
Ring! Call number 69
Ring! Call number 70
Ring! Call number 71
Ring! Call number 72
Ring! Call number 73
Ring! Call number 74
Ring! Call number 75
Ring! Call number 76
Ring! Call number 77
Ring! Call number 78
Ring! Call number 79
Ring! Call number 80
Ring! Call number 81
Ring! Call number 82
Ring! Call number 83
Ring! Call number 84
Ring! Call number 85
Ring! Call number 86
Ring! Call number 87
Ring! Call number 88
Ring! Call number 89
Ring! Call number 90
Ring! Call number 91
Ring! Call number 92
Ring! Call number 93
Ring! Call number 94
Ring! Call number 95
Ring! Call number 96
Ring! Call number 97
Ring! Call number 98
Ring! Call number 99
Ring! Call number 100
====================
You can keep working on this exercise,
or jump into the next one by removing the `I AM NOT DONE` comment:
2 | // Make me compile! Execute `rustlings hint functions3` for hints :)
3 |
4 | // I AM NOT DONE
5 |
6 | fn main() {
通りました.
functons4.rs
Debugging ⚠️ Compiling of exercises/functions/functions4.rs failed! Please try again. Here's the output:
error: expected type, found `{`
--> exercises/functions/functions4.rs:14:30
|
14 | fn sale_price(price: i32) -> {
| ^ expected type
error: aborting due to previous error
型名が必要そう.
を見ると大事なことが幾つも書いてある:
- 戻り値を持つ関数の戻り値には名前を付けないが,
-> <type-name>
で注釈が必要 - 関数の戻り値は最後に評価される式の値(the value of the expression)
とりあえず sale_price(price: i32) ->
を sale_price(price: i32) -> i32
にしてトライ.
🎉 🎉 The code is compiling! 🎉 🎉
Output:
====================
Your sale price is 48
====================
You can keep working on this exercise,
or jump into the next one by removing the `I AM NOT DONE` comment:
5 | // 10 Rustbucks off, but if it's an odd number, it's 3 Rustbucks off.
6 |
7 | // I AM NOT DONE
8 |
9 | fn main() {
OK だそう.次.
functons5.rs
Debugging 言っている意味(要求内容)は分かるけど理由が理解できないケースがきた:
⚠️ Compiling of exercises/functions/functions5.rs failed! Please try again. Here's the output:
error[E0308]: mismatched types
--> exercises/functions/functions5.rs:11:24
|
11 | fn square(num: i32) -> i32 {
| ------ ^^^ expected `i32`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
12 | num * num;
| - help: consider removing this semicolon
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
直接的には num * num;
-> num * num
を期待されていそうだけど,敢えて違う方向で
-
num * num;
->let squared = num * num;
としてみる:
⚠️ Compiling of exercises/functions/functions5.rs failed! Please try again. Here's the output:
error[E0308]: mismatched types
--> exercises/functions/functions5.rs:11:24
|
11 | fn square(num: i32) -> i32 {
| ------ ^^^ expected `i32`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
ダメでした.宣言時に型注釈を加えて
-
let squared = num * num;
->let squared: i32 = num * num;
としてみると...
⚠️ Compiling of exercises/functions/functions5.rs failed! Please try again. Here's the output:
error[E0308]: mismatched types
--> exercises/functions/functions5.rs:11:24
|
11 | fn square(num: i32) -> i32 {
| ------ ^^^ expected `i32`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
やはりダメみたい.というわけで,i32
型を返却していない判定されている模様.
つまり,「関数の戻り値は最後に評価される式の値(the value of the expression)」は拡大解釈であって,本当は
- セミコロンなしの単なる式
-
return
キーワード(慣習的に early return 時のみだそう)
に限られるらしい.この辺は謎なので別途理解を深める(後はセミコロンなしの戻り値も美的感覚を逆撫でされる).
とりあえずセミコロンなしのシンプルなソリューションで解決:
-
let squared = num * num;
->num * num
テストも通過
🎉 🎉 The code is compiling! 🎉 🎉
Output:
====================
The answer is 9
====================
You can keep working on this exercise,
or jump into the next one by removing the `I AM NOT DONE` comment:
2 | // Make me compile! Execute `rustlings hint functions5` for hints :)
3 |
4 | // I AM NOT DONE
5 |
6 | fn main() {
これで functions 編は終わり.
次回予告
⚠️ Compiling of exercises/if/if1.rs failed! Please try again. Here's the output:
error[E0308]: mismatched types
--> exercises/if/if1.rs:5:34
|
5 | pub fn bigger(a: i32, b: i32) -> i32 {
| ------ ^^^ expected `i32`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
functons5.rs
と似たようなケースの予感.
Discussion