2016-09-21 9 views
57

Here「注:_は「私はその価値を気にしません」という意味ですが、JavaScriptから来て、その意味を理解していません。なぜ迅速に下線が必要なのですか?

私は印刷にこれらの機能を得ることができる唯一の方法は、パラメータの前にアンダースコアを使用していた:

func divmod(_ a: Int, _ b:Int) -> (Int, Int) { 
    return (a/b, a % b) 
} 

print(divmod(7, 3)) 
print(divmod(5, 2)) 
print(divmod(12,4)) 

私はすべてのエラーを避けるために、このようにそれを記述する必要があり、アンダースコアなし:

func divmod(a: Int, b:Int) -> (Int, Int) { 
    return (a/b, a % b) 
} 

print(divmod(a: 7, b: 3)) 
print(divmod(a: 5, b: 2)) 
print(divmod(a: 12,b: 4)) 

このアンダースコアの使用方法はわかりません。どのように、どうやってこれらのアンダースコアを使うのですか?

答えて

143

であるのに対し、名前は

divmod(_:_:) 

であり、さまざまな使用例をいくつかのニュアンスがありますが、一般的にアンダースコアが「これを無視」を意味します。


新しい関数を宣言するとき、アンダースコアが呼び出されたときのパラメータは何のラベルを持つべきではないということスウィフトを伝えます - それはあなたが見ているケースです。より完全な関数宣言は、次のようになります。

func myFunc(label name: Int) // call it like myFunc(label: 3) 

"label"は関数の呼び出し時に存在する必要があります。 (Swift 3以降は、デフォルトですべての引数にラベルが必要です。) "name"は、関数内で使用するその引数の変数名です。短い形式は、次のようになります。

func myFunc(name: Int) // call it like myFunc(name: 3) 

これは外部の引数のラベルや内部パラメータ名の両方に同じ言葉を使用することができますショートカットです。これはfunc myFunc(name name: Int)に相当します。

パラメーターラベルなしで関数を呼び出し可能にする場合は、アンダースコア_を使用して、ラベルを何も/無視しないでください。 (この場合、パラメータを使用できるようにするには、内部名を指定する必要があります。代入文で)

func myFunc(_ name: Int) // call it like myFunc(3) 

、アンダースコアは "何にも割り当てないでください" という意味です。結果を返すが、返された値を気にしない関数を呼び出す場合は、これを使用できます。

_ = someFunction() 

記事では、あなたが、返されたタプルの一つの要素を無視するためにリンクされ好きか、:あなたは、いくつかの定義された関数型を実装閉鎖を書くとき

let (x, _) = someFunctionThatReturnsXandY() 

、することができますアンダースコアを使用して特定のパラメータを無視します。プロトコルを採用しているか、スーパークラスのメソッドをオーバーライドする関数を宣言するとき

PHPhotoLibrary.performChanges({ /* some changes */ }, 
    completionHandler: { success, _ in // don't care about error 
     if success { print("yay") } 
    }) 

同様に、あなたはパラメータを無視するパラメータに_を使用することができます。プロトコル/スーパークラスはパラメータにラベルがないことを定義することもできるので、1行に2つのアンダースコアを指定することもできます。

class MyView: NSView { 
    override func mouseDown(with _: NSEvent) { 
     // don't care about event, do same thing for every mouse down 
    } 
    override func draw(_ _: NSRect) { 
     // don't care about dirty rect, always redraw the whole view 
    } 
} 

最後の2つのスタイルにやや関連:定数、ローカル変数を/バインドするフロー制御構文を使用した場合、あなたはそれを無視する_を使用することができます。あなたはそのメンバーへのアクセスを必要とせずにシーケンスを反復処理したい場合たとえば、:あなたはswitch文でのタプルの例を結合している場合

for _ in 1...20 { // or 0..<20 
    // do something 20 times 
} 

、アンダースコアは、こののように、ワイルドカードとして動作することができます例:The Swift Programming Languageで短縮されたもの:

switch somePoint { // somePoint is an (Int, Int) tuple 
case (0, 0): 
    print("(0, 0) is at the origin") 
case (_, 0): 
    print("(\(somePoint.0), 0) is on the x-axis") 
case (0, _): 
    print("(0, \(somePoint.1)) is on the y-axis") 
default: 
    print("(\(somePoint.0), \(somePoint.1)) isn't on an axis") 
} 
+2

大きな説明、ありがとうございました! –

+1

あなたは単に非常に良いユースケースを忘れてしまったと思います。場合によっては配列や辞書のオブジェクトの**番号**にしか興味がなく、実際の値には興味がない*場合もあります。だからあなたは 'forArray {do stuff}'のようなことをします。通常、値を気にするときは、 'someArrayのオブジェクトのために{do stuff}' – Honey

+0

良い提案です。私はそれを加えました。 – rickster

1

スウィフト3以降、関数呼び出しでパラメータ名を指定することは必須となりました。したがって、それはswift 2で書かれたコードに大きな問題を引き起こす可能性があるため、宣言でアンダースコアを使用して呼び出し時にパラメータ名を書く必要がなくなります。この場合、「外部パラメータ名は気にしない」と言っています。外部パラメータ名は、内部ではなく関数外(呼び出し時)のパラメータを呼び出す場所です。これらの外部パラメータ名は、引数ラベルと呼ばれます。 http://ericasadun.com/2016/02/09/the-trouble-with-argument-labels-some-thoughts/ ...パラメータに2つの名前がどのように与えられているかを見てください。まず最初はアンダースコアがどこに行くのかです。これがうまくいくことを願って、まだ混乱しているかどうか尋ねます。

1
func divmod(_ a: Int, _ b:Int) -> (Int, Int) { 
    return (a/b, a % b) 
} 

func divmod(a: Int, b:Int) -> (Int, Int) { 
    return (a/b, a % b) 
} 

_は、パラメータ名のプレースホルダです。あなたの例では、それらを別々に呼び出す、2番目の関数では、パラメータ名a: 1を書く必要があります。

スウィフトの関数名規則はfuncName(param1:param2:)であり、関数の名前を作成するにはプレースホルダーとして_が必要です。最初の名前で

divmod(a:b:) 
関連する問題