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

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

ただいまの
回答率

91.00%

  • JavaScript

    13835questions

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

  • Java

    12163questions

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

  • Swift

    6092questions

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

  • Objective-C

    1128questions

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

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

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 212

keys

score 150

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

func createMovieFrom(image: UIImage, duration:Int) -> URL{
        var images = [UIImage]()
        var index = duration
        while(index > 0){
            images.append(image)
            index -= 1
        }
        return self.createMovieFromSource(images: images, extractor: {(inputObject:AnyObject) -> UIImage? in
        return inputObject as? UIImage})
    }

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

 クロージャ

//クロージャ
var block = {(a: String) -> String in
    return a
}
print(block("a")) // => a

 関数

//関数
func block2() {
    print("a")
}
block2()  // => a
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • MasakiHori

    2017/09/06 17:21

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

    キャンセル

回答 3

checkベストアンサー

+3

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

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

let original: [Int]  // これが元の配列です。中身はすでに入っているものとします。

var new = [Int]()

for elem in original{
    if elem % 2 == 0 {
        new.append(elem)
    }
}

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

let original: [Int]  // これが元の配列です。中身はすでに入っているものとします。

func odd(i: Int) -> Bool {
    return i % 2 == 0
}

let new = original.filter(odd)

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

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

let original: [Int]  // これが元の配列です。中身はすでに入っているものとします。

let new = original.filter( { (i: Int) -> Bool in return i % 2 == 0 } )

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

let original: [Int]  // これが元の配列です。中身はすでに入っているものとします。

let new = original.filter( { $0 % 2 == 0 } )

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

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

let original: [Int]  // これが元の配列です。中身はすでに入っているものとします。

let new = original.filter { $0 % 2 == 0 }

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/07 10:21

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

    キャンセル

+1

=== 追記 ===

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

==========

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

func createMovieFrom(image: UIImage, duration: Int) -> URL {
    // ...

    let sourceURL = self.createMovieFromSource(images: images, extractor: { inputObject -> UIImage? in
        return inputObject as? UIImage
    }

    return sourceURL
}

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

let alert = UIAlertController(title: "title", message: "message", prefereedStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: { action in 
    print("OK")
}
let  cancelAction = UIAlertAction(title: "Cancel", style: .default, hander: { action in
    print("Cancel")
}

alert.addAction(okAction)
alert.addAction(cancelAction)

self.present(alert, animated: true, completion: {
    print("completed")
}

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/06 17:59

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

    キャンセル

  • 2017/09/06 18:24

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

    キャンセル

0

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 91.00%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    13835questions

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

  • Java

    12163questions

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

  • Swift

    6092questions

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

  • Objective-C

    1128questions

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

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