この本を見ながら進めてる↓
前回⇒「【Swift奮闘記ep23】関数オブジェクト前半(関数の型、呼び出し、引数と戻り値がない関数の型)」
タイトルでなんとなく内容が予想できるのだが、前回学んだ関数オブジェクトを引数や戻り値として使ってみようということだ。
ではさっそく行ってみよう。
関数を引数にする
そもそも関数とは「こうこう、こういった処理をしてください」という指示をまとめたものである。
Swiftの特徴として、こういった「指示をまとめたもの」(=「関数」)を引数や戻り値に使用することができるのである。
実際にコードをみながら考えていこう。
1 2 3 4 5 |
func addTitle(name: String) -> String { return "\(name)さん” } |
引数として与えられたnameに”さん”を付けて戻す関数である。
この関数を引数とする関数について定義してみよう。
関数を引数や戻り値で定義するには、引数の型に関数の型を指定します。
これむちゃくちゃ重要だと思う!
関数の型については前回「【Swift奮闘記ep23】関数オブジェクト前半(関数の型、呼び出し、引数と戻り値がない関数の型)」でやったがここですぐに活かされるわけだ。
上記の関数addTitleの関数の型は(String) -> String だ。
よってこれを引数の部分に書き込めばいい。
下記のように「こんにちは○○!」というメッセージを出力する関数を定義してみる。
1 2 3 4 5 6 7 |
func sayHello(name: String, function: (String) -> String) { let result = function(name) print("こんにちは、\(result)!") } |
sayHelloという関数は、1つ目の引数がname、2つ目の引数が(String)->Stringという型である。
定数resultに「引数で代入された関数の引数がnameの時の値」を代入する。
どうにも紛らわしくなってきたがしょうがない。
sayHello関数を実行するためには以下のようなコードが必要となる。
1 |
sayHello(name: ”太郎”, function: addTitle) |
こうすることで1つめの引数で”太郎”を2つめの引数でaddTitleという関数を取ることができる。
結果”太郎”にさんがつけられる(addTitle関数)
こんにちは、○○!と表示させられる(sayHello関数)
つまりコンソールには以下のように表示されるという事だ。
こんにちは、太郎さん!
さらに引数としてつかう関数は 型が(String)->Stringであればなんでもいいので
1 2 3 4 5 |
func addMister(name: String) -> String { retrun "Mr.\(name)!” } |
という関数も「関数sayHelloの引数」にしてみよう。
1 |
sayHello(name: John, function: addMister) |
これによって以下のようにコンソールに表示されるのである。
こんにちは、Mr . John!
関数オブジェクトを戻り値にする
さて、お次は関数を戻り値として使ってみることにする。
よくわからないんだが、関数を戻り値に指定するという事は
「関数を取得するための関数を作ることができる」
ということらしい。
実際にコードを見ていけば関数を戻り値にする意味が分かると思う。
※追記
「Aという関数をもってくるか(使うか)どうかをBという関数が決める」みたいな感覚。
って考えると意外と需要はありそう。
まずは関数を二つ用意する。いずれも関数の型は(String)-> Void だ。
※追記
引数がString型、戻り値はないのでVoid
1 2 3 4 5 |
func sayGoodMorning(name: String) { print("おはよう、\(name)!”) } |
1 2 3 4 5 |
func sayHello(name: String) { print("こんにちは、\(name)!”) } |
これらの2つをIf文で場合分けして、戻り値として使ってみよう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
func greet(isMorning: Bool) -> (String)->Void { if isMornning { return sayGoodMorning } else { return sayHello } } |
greetという関数を定義する。引数はBool型のisMorning。戻り値を型が(String)->Voidの関数であるものとする。
もしisMorningがtrueだったらsayMorningを返して、もしfalseだったらsayHelloを返すという内容。
1 2 3 |
let say = greet(isMorning: true) say("太郎") |
定数sayに引数isMorningがtrueの関数greetを代入するとその結果、戻り値が代入される。
戻り値が関数であるため、すなわちsay(“太郎”)で引数nameを指定して関数sayMorningが実行されたことになる。
※追記
sayは型を指定しなくていいのかな?と疑問に思ったが、そういえば戻り値が設定されている関数は普通に代入できたね。
さらに戻り値の型が(String)->Voidなのでこの定数sayの型も(String)->Voidとなる。
この時点でsay( )はsayGoodMorning(name:)と同じものとして扱うことができる。
実行結果は以下。
おはよう、太郎!
また、isMorningをfalseにしていれば、実行結果は「こんにちは、太郎!」となるわけである。
以上が関数を引数や戻り値にしてみるやり方。
コメント