#レベル1のオブジェクトモジュールが閉じている

45289 ワード

今日の文章は...とても長いです.とても巨大です...でもVelogは...字に色をつけるのは面倒です.黒.
🍫 タスクへの移動(強く推奨)

#Closer Close?


関数とメソッドはモジュールから始まります.func _____として定義される関数および方法は、厳密にはモジュールである(named closure).
一般的にCloserといえば、名前のないunnamed closureを指す.
✔︎ closure
  • **이름 없는 함수 ⇒ 클로저**
  • 名前付き関数♥関数/メソッド
  • したがって,Closer関数であるため,関数式プログラミングが可能である.
    これはsweet関数が1級オブジェクト(1 st class object)の特性を持っているためです...
    ✔︎ **1급 객체 ** ?
    1位の市民のように、多くの権限を得ました!
    どれくらいできますか.
    1. 변수 또는 상수에 `함수`를 담을 수 있다.
    2. 인자(파라미터)로 `함수`를 전달할 수 있다.
    3. 반환값(리턴벨류)으로 `함수`를 전달할 수 있다.
    を選択します.そのため、
    1. 변수 또는 상수에 `클로저`를 담을 수 있다.
    2. 인자(파라미터)로 `클로저`를 전달할 수 있다.
    3. 반환값(리턴벨류)으로 `클로저`를 전달할 수 있다.
    そう言ってもいいです.

    #一級オブジェクト関数


    👉 (String) -> BoolFunction Typeです
    //(String) -> Bool
    let tupleExample = (1, true, "dkd", 3.3)
    tupleExample.0 //.을 통해서 접근
    
    let tupleExample: (Int, Bool, String, Double)
    このタイプの図面が流れているように、関数のタイプも流れています!
    func hello(nickname: String) -> String {
        return "저는 \(nickname)입니다."
    }
    
    hello
    グラウンドに関数名を入力すれば、関数のタイプがわかります
    String) -> String
    func hello(nickname: String) -> String {
        return "저는 \(nickname)입니다."
    }
    
    // Function Type 2. (String, Int) -> String
    func hello(nickname: String, userAge: Int) -> String {
        return "저는 \(nickname), \(userAge)입니다."
    }
    
    // Function Type 2. () -> Void, () -> ()
    func hello() -> Void {
        print("안녕하세요, 반갑습니니다.")
    }
    let a = helloハロー多すぎる!使いたいものを選びたい場合はどうすればいいですか?

    #区分関数

    let a: (String)-> String = hello
    let b: (String, Int) -> String = hello
    このように類型化によって類型を説明すれば、同じ関数名があっても、欲しいものを使い分けることができます!

    # 1. 変数または定数に関数を含めることができます。


    👉 同じ名前の関数が多い場合、特定の関数を使用するために関数の識別子が使用されます.
    let tupleExample = (1, true, "dkd", 3.3)
    tupleExample.0 //.을 통해서 접근
    
    func hello(userName: String) -> String {
        return "저는 \(nickname)입니다."
    👉 省略タイプ宣言は、関数の使用を区別することもできます.
    let a: (String)-> String = hello(nickName:)
    let b: (String, Int) -> String = hello(nickname: userAge:)
    👉 定数bには関数helloが含まれているので、helloのようにbを使用することができます.
    b("minsoo", 33)

    #2.関数の戻りタイプとして関数を使用できます。

    //2. 함수의 반환 타입으로 함수를 사용할 수 있다. 구조체 클래스 등 반환값으로 사용할 수 있음.
    
    //()->String
    func currentAccount() -> String {
        return "계좌 있음"
    }
    
    func noCurrentAccount() -> String {
        return "계좌 없음"
    }
    // 가장 왼쪽에 위치한 ->를 기준으로, 오른쪽에 놓인 모든 타입은 반환값을 의미.
    // 반환값에 대해서 보통 괄호를 쓰지 않고 그냥 쓰는 편인다.
    func checkBank(bank: String) -> () -> String {
        let bankArray = ["우리", "KB", "신한"]
        return bankArray.contains(bank) ? currentAccount : noCurrentAccount
    }
    
    let minsu = checkBank(bank: "농협")
    これまでは,代入関数自体の状態だけでなく実行されてきた.
    実行するためには、以下に示すように、実行関数の演算子()を書く必要があります.
    minsu()

    #計算機の例


    (Int,Int)->Intタイプの計算機関数を作成!
    func plus(a: Int, b: Int) -> Int {
        return a + b
    }
    func minus(a: Int, b: Int) -> Int {
        return a - b
    }
    func multiply(a: Int, b: Int) -> Int {
        return a * b
    }
    func divide(a: Int, b: Int) -> Int {
        return a / b
    }
    
    func calculate(operand: String) -> (Int, Int) -> Int{
        
        switch operand {
        case "+": return plus
        case "-": return minus
        case "*": return multiply
        case "/": return divide
        default: return plus
        }
    }
    関数を結果に代入すると、
    let result = calculate(perand: "-")
    これは関数をresultという定数に代入し、Xを実行します.
    ダイレクトコールを実行
    result(5, 3) //2
    そして上の2つは一度にメモすることができます.しかし、可読性のためには単独で書くのが一般的です
    let result = calculate(operand:"-")(4,3)

    3.関数は、関数のパラメータ値として使用できます。


    コールバック関数としてよく使用されます!콜백함수:特定のパーティションの実行が完了した後、システムが呼び出す関数
    func oddNumber() {
        print("홀수")
    }
    
    func evenNumber() {
        print("짝수")
    }
     // ()->() : 함수의 타입을 적어준 것!
    func resultNumber(base: Int, odd: ()->(), even: ()->()) {
        return base.isMultiple(of: 2) ? odd() : even()
    }
    
    // 타입에 맞는 함수를 매개변수로 넣어 주었다!
    resultNumber(base: 9, odd: oddNumber, even: evenNumber)
    パラメータで関数を渡すことができます!문제:どのような関数が入っていても、タイプが適切であればいいです.
    このような実質的な演算は、パラメータ値としての関数に依存し、仲介としてのみ機能し、**브로커**と呼ばれる.
    func plusNumber() {
        print("더하기")
    }
    
    func minusNumber() {
        print("뺴기")
    }
    ただし、1回の呼び出しに多くの関数を作成することは望ましくありません.
    익명함수を使用(モジュール出現、、、)
    :多くの関数を作成する必要がないという利点があります.

    上の図に示すように、関数がブロック処理されると、엔터で次のような匿名関数になります.

    これは、最後のパラメータの名前のみを残して省略するため、**익명함수**と呼ぶ.

    #一級オブジェクトキャビネット

    resultNumber(base: 9) {
    	// 첫번째 매개변수는 생략, 마지막 매개변수만 남는다.
        print("Success")
    } even: {
        print("failed")
    }
    Closer:閉じました.
    大きな関数の内部にはcloserという小さな関数があり、closerは外部の大きな関数のライフサイクルの影響を受けます.
    綱引きゲームの例を考えてみましょう.
    // 외부함수
    func drawingGame(item: Int) -> String { 
    		
    		// 내부함수    
        func luckyNumber(number: Int) -> String {
            return "\(item * number * Int.random(in: 1...5))"
        }
        
        let result = luckyNumber(number: item * 2)
        
        return result
    }
    
    drawingGame(item: 10)
    ここで、drawingGameという外部関数のライフサイクルが終了します(戻る場合)
    →luckyNumberという内部関数のライフサイクルも終了します.( **은닉성** )

    #内部関数を返す外部関数を作成できます。

    func drawingGame2(item: Int)-> (Int)-> String {
        func luckyNumber(number: Int) -> String {
            return "\(item * number * Int.random(in: 1...5))"
        }
        
        return luckyNumber
    }
    let  luckyNumber2 = drawingGame2(item: 10)
    //외부함수는 생명 주기가 끝난 상태
    
    luckyNumber2(2)
    // 외부함수의 생명주기가 끝나는데, 내부함수를 반환했기 때문에 -> 내부 함수는 계속사용할 수 있는 문제 발생.
    →暗黙的な内部関数を外部関数の実行結果に戻す場合、内部関数は外部からアクセスすることもできます.今呼んでもいいです.これはライフサイクルにも影響します.外部関数が終了しても、内部関数は存在します.
    ✔勘定科目の外部関数のライフサイクルが終了しました.これは、外部関数のパラメータも終了したことを意味します.勘定科目などです.
    →どこから持ってきたの?
    item

    #キャプチャモジュール


    内部関数の周囲の領域変数または定数は、
  • エンクロージャによって一緒に格納されます.
  • 周囲環境に含まれる変数または定数のタイプが資料型または構造体資料型の場合に発生する.
  • ✔✐SWIFTは名前のない関数エンクロージャを使用しており、周囲環境(内部関数の変数や定数)から値を取得するツールとして使用されることが多い.

    もう一度関数を見てみましょう。


    定数または変数には、1.**キャプチャモジュール**を含めることができます。

    func studyiOS() {
        print("iOS 개발자를 위해 열공중")
    }
    
    let studyiOSHarder = {
        print("iOS 개발자를 위해 열공중")
    }
    **경량 문법**で作成された클로저関数をcloserという匿名関数として使用します.以下に示します.定数にエンクロージャを入れて作りました.必要な形だけを作る.
    エンクロージャタイプを明確に記入した場合は、以下のようになります.公式関数の内容はキーワードfuncの後に書かれている.
    let studyiOSHarder2 = { () -> () in
        print("iOS 개발자를 위해 열공중")
    }
    ✔()->(印刷)(「iOS開発者のために開く」)
    inを基準として()->()をHead,print(「iOS開発者のための空」をBodyとする.
    呼ぶときは定数の名前を書きます.
    studyiOSHarder2
    モジュールを作成した後、すぐに実行する場合は、呼び出し演算子studyiOS()が追加されます.
    let studyiOSHarder3 = { () -> () in
        print("iOS 개발자를 위해 열공중")
    }()

    パラメータにinを入れることができます。(feat.軽量級文法)


    👉 このエンクロージャをパラメータ値フォーマットに入れましょう.以下の()->()は、定数というモジュールの()という従来の例を含むことができる.
    func getStudyWithMe(study: ()-> ()) {
        study()
    }
    
    getStudyWithMe(study:  { () -> () in
        print("iOS 개발자를 위해 열공중")
    })
    ✔АААААААААААААААА\104
    👉 パラメータ位置のキャビネットに置いても、外に引き出すことができます.클로저パラメータの値形式(上記のように)ではなく、関数の後に取り出して記すことをstudyiOSHarder2と呼び、このとき研究と同じ**인라인클로저**とする.
    getStudyWithMe(){ () -> () in
        print("iOS 개발자를 위해 열공중")
    }
    整理すると、

  • 最後のパラメータがキャビネットの場合(パラメータはニンジン)

  • パラメータ名をスキップ
    前述の例と同様に、パラメータがエンクロージャの場合は、関数を呼び出す演算子**단, 함수의 마지막 파라미터가 클로저인 경우에!**を省略することもできます.すなわち、以下のようにすることができる.
  • getStudyWithMe { () -> () in
        print("iOS 개발자를 위해 열공중")
    }
    👉 上には定数**트레일링 클로저(Trailing Closuer)**が入っています.また、エンクロージャを含む定数または変数をパラメータに入れることもできます.
    getStudyWithMe(study: studyiOSHarder2)

    #モジュール軽量レベルの構文


    上の図に示すように、より簡単で、読みやすいのは매개변수의 이름은 생략であることを示しています.先ほど述べたように,複雑なコードの構文構造を減らし,可読性を向上させるためである.
    今から減らそう
    削減するには、次の手順に従います.
    func todayNumber(result: (Int) -> String) {
        result(Int.random(in: 1...100))
    }
    todayNumber(result: { (number: Int) -> String in
        return "행운의 숫자는 \(number)"
    })
    ✔申パラメータのタイプは、戻り値を省略できるタイプ
    todayNumber(result: { (number~~: Int~~) -> ~~String~~ in
        return "행운의 숫자는 \(number)"
    })
    
    todayNumber(result: { (number)  in
        return "행운의 숫자는 \(number)"
    })
    残りのパラメータの名前は省略できます.パラメータを削除すると、独自に残した**트레일링 클로저**も削除されます.
    todayNumber(result: { ~~(number)~~  ~~in~~
        return "행운의 숫자는 \(number)"
    })
    
    todayNumber(result: {
        return "행운의 숫자는 \(number)" //ERROR
    })
    ただしERRORは上に表示されますパラメータとして受信されていない場合はnumber変数は内部で使用できません.このとき、指定された内部定数()を用いることができる.
    todayNumber(result: {
        return "행운의 숫자는 \($0)"
    })
    👉 最後に、関数内部に戻り値のみが存在する場合、studyiOSHarder2度を省略することができる.
    todayNumber(result: {
        "행운의 숫자는 \($0)"
    })
    👉 スターリング郡を解消すれば、最終的には以下のようになります.
    todayNumber{"\($0)"}
    🙌 このような長いプロセスを経て、次のように使用することもできます.
    todayNumber { value in
        print("하하하하")
        return "\(value)입니다."
    }
    🔖 リファレンス
    ∙SSAC iOS開発者デビューコースの講義と講義資料
    https://babbab2.tistory.com/82