基本概念
- キーワードを使用して
fn
関数を宣言します。関数のパラメーターと戻り値の型は手動で記述する必要があります。fn add_two(num: i32) -> i32 { num + 2 }
- 関数の最後の式にセミコロンが含まれていない場合、関数の結果として返されるか、明示的に記述できます。
return
fn add_two(num: i32) -> i32 { num + 2 } fn add_two(num: i32) -> i32 { return num + 2; }
- 関数は関数内で宣言したり、宣言前に使用したりできますが、無制限ではなく有効なスコープ内にある必要があります。
fn main() { { // OK my_fn(); fn my_fn(){ //... } // OK my_fn(); } // err my_fn(); }
- 関数宣言と関数式については議論がありません (JS と比較して)
閉鎖
現代言語としては Lambda (無名関数) も存在しますが、 Rust ではクロージャと呼ばれます。
// 简写形式
let add_one = |num| num + 1;
// 完整
let add_one = |num: i32| -> i32 {
num + 1
};
関数パラメータとして使用します。
fn main() {
let num = 10;
let arr = [1, 2, 3, 4, 5];
let arr: Vec<i32> = arr.iter().map(|item| item * num).collect();
// [10, 20, 30, 40, 50]
println!("{:?}", arr);
}
こうやって見ると、フロントエンド開発者にとっては奇妙に思えますが、これもクロージャと言えるのでしょうか?これは新しいスキンを備えたアロー関数に似ていますが、これについては説明が必要です。
魔法の関数
Rust は JavaScript と同様に、関数内で関数を宣言できますが、関数は関数スコープ外のデータを読み取ることはできません。
function main() {
let num = 10;
function log(){
console.log(num);
}
// OK
log();
}
fn main() {
let num = 10;
fn log() {
// 错误,不存在 num
println!("{}", num);
}
log();
}
外部データを読み取りたい場合は、それをクロージャー形式に切り替える必要があります。
fn main() {
let num = 10;
let log = || println!("{}", num);
// OK
log();
}
ちょっと待ってください。関数は現在のスコープ内のデータを読み取ることができません。実際には、JS のように記述することはできますが、そのように使用することはできません。データを使用したい場合は、パラメーターを明示的に渡してください。 。
このように考えると、将来的には関数本体内のすべての関数宣言にクロージャを使用するのが良いのではないでしょうか? いいえ、クロージャは外部データを読み取ることができますが、自己再帰的に呼び出すことはできません。
この議論は、フォーラムのディスカッションを参照できます。
まとめ
関数本体内で関数を宣言できますが、外部データを読み取ることはできませんが、再帰には影響せず、従来の言語と同様に、データを関数のパラメータとして渡すことができます。
この点で、再帰を使用する場合は、関数本体の外に再帰関数を記述するのが最善です。これは、通常の関数を実行コードに記述する利点がなく、分離後の方が整理できるためです。
JS 関数本体内の関数の利点は、不必要なパラメーターの受け渡しを減らすことです。
クロージャはデータを読み取ることができますが、それ自体を呼び出して再帰を形成することはできず、関数パラメータ (Lambda の本拠地) として使用されることがよくあります。
逆に、スコープ内のあらゆるデータに自由にアクセスできる JS のような言語も奇妙です。