2017-05-21 5 views
1

私は迅速に習得しようとしていますが、クロージャが掛かっていましたが、依然として質問する質問があり、インターネット上で回答が見つからず、ここで尋ねるのが適切ですが、私は本当にこれに関する答えが必要です。 クロージャ機能とファンクションの違い

はどこでクロージャを使用する必要があり、我々は、私が

fCheckGenderの違いとcCheckGenderとを知っていただきたいと思い

var myHuman:Human = Human() 

myHuman.gender = "M" 

myHuman.MyCheckGender() 

次のクラス

class Human{ 
var gender:String? 

private func fCheckGender(pGender:String?){ 
    guard pGender != nil else { 
     print("Gender not specified") 
     return 
    } 

    if pGender == "M"{ 
     print("Male") 
    } 
    else if pGender == "F"{ 
     print("Female") 
    } 
    else{ 
     print("gender Unknown") 
    } 
} 

private func cCheckGender(pGender:@autoclosure()->(String?)){ 

    guard pGender() != nil else { 
     print("Gender not specified") 
     return 
    } 

    if pGender() == "M"{ 
     print("Male") 
    } 
    else if pGender() == "F"{ 
     print("Female") 
    } 
    else{ 
     print("gender Unknown") 
    } 
} 

func MyCheckGender(){ 

    fCheckGender(pGender: gender) 
    cCheckGender(pGender: gender) 
} 

}を持っていると言う

ありがとうございます!

P.S私は意図的にvoid-> Stringを使用しました。()->(String?) このシナリオの違いを知りたいだけです。私は私の悪い英語

+0

から閉鎖、その後、自動閉鎖についてお読みくださいを指摘したように、あなたが値を取得するだけでクロージャを使用し、その値を持つ最初のバージョンパラメータが確実に優れているためです。クロージャは、異なるコードを実行できる関数を使用する場合に、パラメータとして最も頻繁に使用されます。したがって、コンテナで呼び出すことができ、指定したコードを実行できるように、mapやreduceのような関数を考えてください。 – Gerriet

+2

言語ガイドの[autoclosures]セクション(https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/)を読んでおくことをお勧めします。 uid/TP40014097-CH11-ID543)。 – Hamish

+0

"closure"は私には "エンクロージャー"なので、クロージャーは渡され、読み込みや解析が可能なデータの代わりに実行可能なコードの束ねられたパッケージです。 –

答えて

3

閉鎖ごめんなさい:

  • 閉鎖は無名の関数のように扱い、コードのブロックです。
  • 引数としてクロージャを渡すと、関数内のコードが引数を呼び出すまでクロージャは評価されません。

オートクロージャー:

  • オートクロージャーはそれと一緒にパラメータの値をパッケージクロージャです。
  • オートクローズを定義するとき、クロージャへのパラメータはありません。 fCheckGendercCheckGender

差:

  • fCheckGender引数としてStringをとります。
  • cCheckGenderは、引数としてクロージャをとります。
  • cCheckGenderが呼び出されると、クロージャに引数が渡されます。この時点で、クロージャは引数として渡されます。クロージャは実行されません。関数内でクロージャパラメータが使用されている場合にのみ、クロージャが実行されます。

あなたが述べた例は、その違いを実証するのに最適ではないかもしれません。

のは、別の例を考えてみましょう:

例:

func add(a: Int, b: Int) -> Int { 

    print("add") 

    return a + b 
} 

func f1(pValue: Int) { 

    print("f1") 

    print("value = \(pValue)") 
} 

func f2(pClosure: (Int, Int) -> Int, pA: Int, pB: Int) { 

    print("f2") 

    let value = pClosure(pA, pB) 

    print("value = \(value)") 
} 

//In autoclosure the closure always takes no parameters, because the closure is packaged with parameter values while invoking 
func f3(pClosure: @autoclosure() -> Int) { 

    print("f3") 

    let value = pClosure() 

    print("value = \(value)") 
} 

f1(pValue: add(a: 10, b: 20)) 
print("=====================\n") 

f2(pClosure: add, pA: 10, pB: 20) 
print("=====================\n") 

f3(pClosure: add(a: 10, b: 20)) 
print("=====================\n") 

出力:

add 
f1 
value = 30 
===================== 

f2 
add 
value = 30 
===================== 

f3 
add 
value = 30 
===================== 

例の説明:関数f1のp値で

  • はintです値。
  • したがって、f1が呼び出されると、加算が評価されます。
  • 関数f2およびf3では、Closureはクロージャです。
  • pClosure(closure)は、関数内で呼び出されるまで評価されません。

注:引数としてクロージャを受け付けるf3最初に

  • フォーカス。
  • f3を完全に理解したら、f2を調べます。
  • 自動クロージャは、呼び出されたときにパラメータ値を取得し、後で使用します。

なぜとするときは、私たちが代わりに価値の閉鎖を渡す必要があります:

  • あなたが時間までaddの実行を延期したいシナリオは、あるかもしれません機能f2呼び出しますそれ。
  • 非同期要求を行い、要求が完了したときにコードを実行するシナリオがあります。この場合、クロージャを渡すことができます。 (閉鎖は、常にそれが無名の関数であり、値を返す必要はありませんので、パラメータを受け入れることができます)

をなぜして行うとき、私たちはautoclosureする必要があります:あなたが実行を延期したい

  • addの値を取得し、その値を取得します。

提案:

  • あなたは完全にそれを理解するために初めからスウィフトのドキュメントを通過するために時間がかかるが、それは最高ですが。

参考:

ハミッシュはあなたの例ではhttps://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html

関連する問題