見出し画像

swiftクロージャーのサンプルコード

佐藤剛士氏によるGitHub Gist記事「ClosureSample.swift」をSwift5版、且つ非Playgroundで書き直してみました。

…結局、何某かのClassなりの中で利用する訳だし。

import Foundation

//
//  Closure_Sample.swift
//  SwiftTryCatch
//
//  Created by ISHIKAWA Koutarou on 2020/07/26.
//
class Closure_Sample: NSObject {

	override init() {
		<#code#>
	}


	//MARK: - ネスト関数でクロージャーを作る。

	func outer() -> () -> Void {
		var x: Int = 10

		func inner() {
			print("X is \(x)")

			//inner関数で定義されていないx変数を操作している。
			x  = x + 1
		}

		//関数を返り値として返している
		return inner
	}

	func aaa() {
		let f: () -> Void = self.outer()

		// -> X is 10
		f()

		// -> X is 11
		f()

		// -> X is 12
		f()
	}


	//MARK: - sort(_:)メソッドを使ってクロージャーをもっと見てみる

	var name: Array<String> = [ "Chris", "Alex", "Ewa", "Barry", "Daniella" ]


	/// <#Description#>
	/// - Parameters:
	///   - s1: <#s1 description#>
	///   - s2: <#s2 description#>
	/// - Returns: <#description#>
	func backwards(s1: String, _ s2: String) -> Bool{
		return s1 > s2
	}

	/// <#Description#>
	func bbb1() {
		let reversed: () = self.name.sort(by: self.backwards)

		print(reversed)
	}

	/// 無名関数で実行してみる
	func bbb2() {
		let reversed: () = self.name.sort(by: { (s1: String, s2: String) -> Bool in
			return s1 > s2
		})

		print(reversed)
	}

	/// Swiftは型を推定。配列の型は推定できるから「(String, String) -> Bool」の記述は省略できる
	func bbb3() {
		let reversed: () = self.name.sort(by: {
			s1, s2 in return s1 > s2
		})

		print(reversed)
	}

	/// 処理を単式で書いた場合は戻り値は暗黙に返される。なので'return'の文字はいらない
	func bbb4() {
		let reversed: () = self.name.sort(by: { s1, s2 in s1 > s2 })

		print(reversed)
	}

	/// 略式の引数名。クロージャーには自動的に引数に名前($0,$1,$2)がつけられている。これを使うと、引数の定義をしなくてもいいし、 inの文字もいらない
	func bbb5() {
		let reversed: () = self.name.sort(by: { $0 > $1 })

		print(reversed)
	}

	/// オペレーター関数を使う。SwiftのString型は「>」が使える。「>」は2つのString型引数をもち、戻り値としてBool型を返す。「sort(_:)」にぴったり
	func bbb6() {
		let reversed: () = self.name.sort(by: >)

		print(reversed)
	}

	/// sort関数でもTrailing Closuresを使ってみる
	func bbb7() {
		let reversed: () = self.name.sort() {
			$0 > $1
		}

		print(reversed)
	}

	/// Trailing Closuresで、引数がクロージャー以外なかったら「()」を省略できる
	func bbb8() {
		let reversed: () = self.name.sort{
			$0 > $1
		}

		print(reversed)
	}


	//MARK: - Trailing Closures。関数の引数の末尾(最後)がclosureを受け取る場合、処理部分を外に配置できる。

	/// closureを受け取る関数の定義。「(Int, Int) -> Int」という型の関数を受け取る
	/// - Parameters:
	///   - a: <#a description#>
	///   - b: <#b description#>
	///   - closure: <#closure description#>
	/// - Returns: <#description#>
	func add(_ a: Int, b: Int, closure: (Int, Int) -> Int) -> Int {
		return closure(a, b)
	}

	/// 「add()」を普通に使う
	func iii() {
		var _: Int = self.add(1, b: 5, closure: { (a: Int, b: Int) -> Int in
			return a + b
		})
	}

	/// Trailing版。実際の処理を引数の「()」の外に置いている。
	func jjj() {
		var _: Int = self.add(1, b: 5) {
			$0 + $1
		}
	}
}

この記事が気に入ったらサポートをしてみませんか?