Skip to content

Instantly share code, notes, and snippets.

@KentarouKanno
Last active March 29, 2017 03:48
Show Gist options
  • Save KentarouKanno/45e3bfe52f5e6adb87dd188a9a995186 to your computer and use it in GitHub Desktop.
Save KentarouKanno/45e3bfe52f5e6adb87dd188a9a995186 to your computer and use it in GitHub Desktop.
Closure

Closure

[JavaScript] 猿でもわかるクロージャ超入門 まとめ
私が今までクロージャを理解できなかった理由

★ Basic

{ ([parameters]) -> [return type] in
    [statements]
}

★ Method 引数1つ(Closure (引数1つ、戻り値なし))

let api = APIManager()
api.getImage { [unowned self] (image) in
    self.imageView.image = image
}

class APIManager {
    func  getImage(task: (image: UIImage) -> () ) {
        // ダウンロード処理
        task(image: downloadImage)
    }
}

★ Method 引数1つ(Closure (引数1つ、戻り値有り))

let api = APIManager()
api.getImage { [unowned self] (image) in
    self.imageView.image = image
    
    return image.size
}

func  getImage(task: (image: UIImage) -> CGSize) {
    // ダウンロード処理
    let size = task(image: downloadImage)
}

★ Method 引数1つ(Closure (引数2つ、戻り値有り))

let api = APIManager()
api.getImage { [unowned self] (image, url) in
    self.imageView.image = image
    print(url)
    
    return image.size
}

func  getImage(task: (image: UIImage, url: NSURL) -> CGSize) {
    
    // ダウンロード処理
    let size = task(image: downloadImage, url: url!)
}

★ Method 引数2つ(Closure (引数2つ、戻り値有り))

let url = NSURL(string: "https://teratail.com/uploads/contributed_images/78379419b2c58363c546e3e6e094a8c9.png")!

let api = APIManager()
api.getImage(url, task: { [unowned self] (image, url) in
    self.imageView.image = image
    print(url)
    
    return image.size
})

func  getImage(url: NSURL, task: (image: UIImage, url: NSURL) -> CGSize) {
    
    // ダウンロード成功時
    let size = task(image: downloadImage, url: url)
}


// Trailing Closures

let url = NSURL(string: "https://teratail.com/uploads/contributed_images/78379419b2c58363c546e3e6e094a8c9.png")!

let api = APIManager()
api.getImage(url) { [unowned self] (image, url) in
    self.imageView.image = image
    print(url)
    
    return image.size
}

★ Method Chain

class Sample {
    
    func method1() -> Self {
        print("method1")
        return self
    }
    
    func method2() -> Self {
        print("method2")
        return self
    }
    
    func method3() -> Self {
        print("method3")
        return self
    }
}


let sample = Sample()

// method chain
sample.method1().method2().method3()

/*
method1
method2
method3
*/

★ Closure Chain

class Sample {
    
    func closure1(clo1: (str: String) -> ()) -> Self {
        clo1(str: "closure1")
        return self
    }
    
    func closure2(clo2: (str: String) -> ()) -> Self {
        clo2(str: "closure2")
        return self
    }
    
    func closure3(clo3: (str: String) -> ()) -> Self {
        clo3(str: "closure3")
        return self
    }
}


let sample = Sample()

sample.closure1 { (str) in
    print(str)
    }.closure2 { (str) in
        print(str)
    }.closure3 { (str) in
        print(str)
}

/*
closure1
closure2
closure3
*/

★ シンプルClosure

// 呼び出し
import UIKit
class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let api = APIManager()
        api.getImage { [unowned self] (image) in
            self.imageView.image = image
        }
    }
}


import Foundation
import UIKit

class APIManager {
    
    func  getImage(task: (image: UIImage) -> () ) {
        
        // 画像ダウンロード
        let url = NSURL(string: "https://teratail.com/uploads/contributed_images/78379419b2c58363c546e3e6e094a8c9.png")
        let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: NSOperationQueue.mainQueue())
        let req = NSURLRequest(URL: url!)
        
        let task = session.dataTaskWithRequest(req, completionHandler: { (data, response, error) in
            
            if let imageData = data , downloadImage = UIImage(data: imageData) {
                // ダウンロード成功時
                task(image: downloadImage)
                
            } else {
                // エラー処理
                print("Error!")
            }
        })
        task.resume()
    }
}

★ Closure簡単まとめ

// -------------------------------


// 定義と代入文それぞれに型を書いた場合
var closureA: (Int, Int) -> Int = {(valA: Int, valB: Int) -> Int in
    return valA + valB
}

// 代入文のみに型を書いた場合
var closureB = {(valA: Int, valB: Int) -> Int in
    return valA + valB
}

// 定義文のみに型を書いた場合
var closureC: (Int, Int) -> Int = { valA, valB in
    return valA + valB
}

print(closureA(1,3)) // 4
print(closureB(2,3)) // 5
print(closureC(3,3)) // 6


// 同じ型の別の文を再代入する
closureC = { valA, valB in
    return valA * valB
}

print(closureC(3,3)) // 9

// 引数にクロージャーを取るメソッドを定義
func methodA(valA: Int, valB: Int, closure: (Int, Int) -> Int) {
    print(closure(valA, valB))
}

methodA(3, valB: 3, closure: closureA) // 6
methodA(3, valB: 3, closure: closureC) // 9

// ---------------------------------------

// クロージャー部分を直接記述(型も記述)
methodA(3, valB: 3, closure: {(valA: Int, valB: Int) -> Int in
    return valA - valB
})


// クロージャー部分を直接記述(型は推論)
methodA(3, valB: 3, closure: { valA, valB in
    return valA - valB
})

// クロージャー部分を直接記述(単独式による暗黙的リターン)
methodA(3, valB: 3, closure: { valA, valB in
    valA - valB
})

// トレーリングクロージャー(Trailing Closure)

func methodB(closure: () -> ()) {
    // 処理
}

// トレーリングクロージャーを使用しない場合
methodB({
    
})

// トレーリングクロージャーを使用した場合
methodB { 
    
}

Captuer List

import UIKit

class ViewController: UIViewController {
    
    let v: Int? = 6

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // クロージャーキャプチャリスト
        let clo = { [weak self, max = 5, value = v] (val: Int) -> Bool in
            
            if let value = value {
                print(value + 10)
            }
            
            if let v = self?.v {
                
                if max == v {
                    return true
                }
                return v == 1
            }
            return false
        }
        
        let result = clo(5)
        print(result)
        //=> false
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment