質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

3回答

1271閲覧

関数の実行の結果、リターンで関数を返すってどういうことなのでしょうか。また、その関数の引数にクロージャを持ってくるメリットは何でしょうか。

keys

総合スコア215

Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/09/06 07:48

下記のコード(はSwitです)はとある関数ですが、リターンで関数を実行して、関数の引数にはクロージャが実装されています。

swift

1 2func createMovieFrom(image: UIImage, duration:Int) -> URL{ 3 var images = [UIImage]() 4 var index = duration 5 while(index > 0){ 6 images.append(image) 7 index -= 1 8 } 9 return self.createMovieFromSource(images: images, extractor: {(inputObject:AnyObject) -> UIImage? in 10 return inputObject as? UIImage}) 11 } 12

そもそも、関数の実行の結果、リターンで関数を返すってどういうことなのでしょうか。また、その関数の引数にクロージャを持ってくるメリットは何でしょうか。そもそも、関数の実行の結果、リターンで関数を返すメリットもわからず、コードを書いた人の気持ちがわかりません。野暮ったい質問ですみませんが、クロージャをソース内で多用する利便性を詳しく教えて欲しいです。

クロージャ

swift

1 2//クロージャ 3var block = {(a: String) -> String in 4 return a 5} 6print(block("a")) // => a 7

関数

swift

1 2//関数 3func block2() { 4 print("a") 5} 6block2() // => a 7

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MasakiHori

2017/09/06 08:21

createMovieFrom関数は関数を返してません。 ので、何を聞きたいのかよく分からないです。
guest

回答3

0

ベストアンサー

質問の意味がよくわからないので一般的な回答をさせてもらいます。

Array<Int>から偶数だけ取り出して新しいArray<Int>が欲しいという時、関数を引数に取る関数を使わない場合はこのようになると思います。

swift

1let original: [Int] // これが元の配列です。中身はすでに入っているものとします。 2 3var new = [Int]() 4 5for elem in original{ 6 if elem % 2 == 0 { 7 new.append(elem) 8 } 9} 10

割と普通ですが、関数を引数に取る関数 filterを使うと次のようになります。

swift

1let original: [Int] // これが元の配列です。中身はすでに入っているものとします。 2 3func odd(i: Int) -> Bool { 4 return i % 2 == 0 5} 6 7let new = original.filter(odd)

少し簡略化されました。
さらに新しい配列が変数ではなく定数として宣言できますので、誤って変更を加えてしまうということがなくなります。

関数をわざわざ作らず引数にクロージャを直接渡すとこうなります。

swift

1let original: [Int] // これが元の配列です。中身はすでに入っているものとします。 2 3let new = original.filter( { (i: Int) -> Bool in return i % 2 == 0 } )

さらに簡略化されました。 Swiftの場合クロージャはいろいろな部分が省略可能となっています。一気に全部省略します。

swift

1let original: [Int] // これが元の配列です。中身はすでに入っているものとします。 2 3let new = original.filter( { $0 % 2 == 0 } )

クロージャの引数を省略した場合第1引数は$0で参照します。
簡略化されたうえ読みやすくもなりました。

さらにSwiftでは最後の引数が関数であり、クロージャを渡す場合、クロージャを()の外に置くことができます。

swift

1let original: [Int] // これが元の配列です。中身はすでに入っているものとします。 2 3let new = original.filter { $0 % 2 == 0 }

これが、通常Swiftでfilter関数を使う時に書かれるものです。
最初のものと比べて格段に読みやすく意図が分かりやすくなっていると思います。

関数を引数に取る関数やクロージャを使う意味が分かっていただけましたでしょうか?

投稿2017/09/06 09:22

MasakiHori

総合スコア3384

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keys

2017/09/07 01:21

非常によく理解できました! ありがとうございます。
guest

0

=== 追記 ===

ちなみにreturn createMovieFromSource(...)は関数をreturnしているのではなく,createMovieFromSource(...)でreturnされたものをcreateMovieFrom(...)のreturnとして返しています.

==========

質問内にあるcreateMovieFrom(...)の中でcreateMovieFromSource(...)をreturnしている理由ですが,これは関数をreturnすることで変数宣言を減らすことができます.
記述量が減るのでコードがすっきりする・見やすくなるようになりますが,もしそうしたことで意味がわかりにくくなる場合は変数に入れてからreturnするのもいいと思います.

swift

1func createMovieFrom(image: UIImage, duration: Int) -> URL { 2 // ... 3 4 let sourceURL = self.createMovieFromSource(images: images, extractor: { inputObject -> UIImage? in 5 return inputObject as? UIImage 6 } 7 8 return sourceURL 9}

次に引数にクロージャを利用することについて説明します.
クロージャが使われるのは主に非同期処理や,mapfilter, forEachなどに渡して,配列全てに処理を行ったりすることが多いと思います.
非同期処理では,通信処理などの時間のかかる処理をした後に実行してほしい処理をクロージャで渡して,適切なタイミングで実行してもらったりに使います.
他にもiOSでいうと例えば,UIAlertControllerなどでUIActionにボタンの押された時に実行してほしい処理をクロージャで渡しておいて,ボタンが押されたらその処理を行ってくれます.

swift

1let alert = UIAlertController(title: "title", message: "message", prefereedStyle: .alert) 2let okAction = UIAlertAction(title: "OK", style: .default, handler: { action in 3 print("OK") 4} 5let cancelAction = UIAlertAction(title: "Cancel", style: .default, hander: { action in 6 print("Cancel") 7} 8 9alert.addAction(okAction) 10alert.addAction(cancelAction) 11 12self.present(alert, animated: true, completion: { 13 print("completed") 14}

UIAlertControllerを宣言している時にどのボタンが押されるかはわかりませんが,〇〇(時間のかかる処理)したら実行してほしい時に便利です.

投稿2017/09/06 08:31

編集2017/09/06 09:23
simorgh3196

総合スコア157

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2017/09/06 08:59

MasakiHoriさんからも指摘がありますが、createMovieFrom()は関数を返していません。 表現を変えたほうが良いかと。
simorgh3196

2017/09/06 09:24

コメントありがとうございます.追記しました.
guest

0

処理が非同期で行われるので、クロージャを渡さないと結果を受け取れないとかではないですか?
非同期で重めの処理を行うとユーザーのUI操作をブロックしないのでよくやる手法だと思います

投稿2017/09/06 07:57

編集2017/09/06 08:00
KozoYamagata

総合スコア33

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問