2017-07-17 5 views
1

Swiftでは、カスタム演算子に使用する独自の優先グループを定義できます。私が理解するのに苦労しているのは、ブール値assignmentのプロパティです。 スウィフトプログラミング言語(スイフト3.1)からSwiftでの優先グループの割り当ての理解3.1

:オプションのチェーンを含む動作に使用される場合

優先グループの割り当ては、オペレータの優先順位を指定します。 trueに設定すると、対応する優先グループの演算子は、標準ライブラリからの代入演算子として、オプションの連鎖中に同じグループ化規則を使用します。そうでない場合、falseに設定するか省略すると、優先グループの演算子は、割り当てを実行しない演算子と同じオプションの連鎖規則に従います。

assignmentプロパティの正確な動作についてはあまり言及していません。オプションの連鎖における代入演算子と非代入演算子の違いは何ですか?

Iは、試験のための構造体をAssignmentTestingとともに演算子(+ように動作)(+=ように振る舞う)++=を定義し、++assignment: trueassignment: falseは、これらの行動に影響を与えるにはどうすればよい

precedencegroup AssignmentTrue { 
    assignment: true 
} 

precedencegroup AssignmentFalse { 
    assignment: false 
} 

infix operator ++=: AssignmentTrue 
infix operator ++: AssignmentFalse 

extension Int { 
    static funC++= (left: inout Int, right: Int) { 
     left += right 
    } 

    static funC++ (left: Int, right: Int) -> Int { 
     return left + right 
    } 
} 

struct AssignmentTesting { var number = 0 } 

var assignmentTesting: AssignmentTesting? = AssignmentTesting() 
assignmentTesting?.number ++= 3 // assigns 0 + 3 to assignmentTesting.number 
assignmentTesting!.number ++ 5 // returns 3 + 5 
assignmentTesting?.number // == 3 

?どんな説明も大歓迎です。

答えて

2

あなたのコード例はよく違いを説明します

// assigns (assignmentTesting!.number + 3) to assignmentTesting!.number when assignmentTesting != nil 
// Do nothing when assignmentTesting == nil 
assignmentTesting?.number ++= 3 

// assigns (assignmentTesting!.number + 3) to assignmentTesting!.number when assignmentTesting != nil 
// Crashing when assignmentTesting == nil 
assignmentTesting!.number ++= 3 

// Does not compile 
//assignmentTesting?.number ++ 5 

// returns (assignmentTesting!.number + 5) when assignmentTesting != nil 
// Crashing when assignmentTesting == nil 
assignmentTesting!.number ++ 5 

++=が代入演算子は、オプション・チェーン接続に非常によく似などのassignmentTesting?.number ++= 3作品を:

(assignmentTesting != nil) ? (assignmentTesting!.number ++= 3) as Void? : nil 

しかし++は割り当てないで演算子、assignmentTesting?.number ++ 5はSwiftで有効な式ではなく、次のようには機能しません。

(assignmentTesting != nil) ? (assignmentTesting!.number ++ 5) as Int? : nil 
+0

私はまだ違いを理解していません。なぜinoutパラメータの性質がそれを処理できないのですか?私は、Swift 2.2の動作について素敵な説明を見つけました。「Swift 2.2には、次のように動作する代入修飾子があります:演算子のマークされた代入が任意のチェーンに折りたたまれ、 'foo?.bar + = 2' '(foo?.bar)+ = 2'という型チェックに失敗するのではなく' foo?(.bar + = 2) 'として動作します。この動作は先行グループの代入:trueに渡されます。それはまだ私には漠然としている。 –

+0

Swift 2で代入演算子を宣言する構文を記述し、Swift 3での意味や振る舞いは同じです。 'inout'を使う他の演算子を定義する必要があるかもしれませんが、assign_の_Optional連鎖は望ましくありません。 – OOPer

+0

代入演算子と非代入演算子の間のオプションの連鎖の違いについて、詳しく説明できますか?私は非常に興味があるのですが、なぜオプションチェーンで代入を処理するために必要な別のパラメータがあるのですか? 'precedencegroup'に新しい構文を導入することは十分に重要です。 –

0

違いの簡単な説明は、オプションの連鎖中に割り当て解除可能な演算子を使用するとコードを遵守できないことです。

assignmentTesting?.number ++= 3には、が+=と同じように動作するように設定されています。ただし、assignment: falseとして、優先グループ内の演算子は、代入を実行しない演算子と同じオプションの連鎖規則に従います。割り当てが実行されていないので、コンパイラは不平を言います。

したがって、AssignmentPrecedence++=を埋め込む必要があります。これは、オプションの連鎖中に割り当てることができます。

infix operator ++=: AssignmentPrecedence 

または

precedencegroup AssignmentTrue { 
    assignment: true 
} 
infix operator ++=: AssignmentTrue 

更新

あなたの例では、実際に自己説明されていて、また、オペレータが割り当てをマークし任意の連鎖の中に折り畳まれます指摘しています、 foo?.bar += 2はtype-checに失敗する代わりにfoo?(.bar += 2)として機能することができますkとして(foo?.bar) += 2。この動作は、先行グループSE-0077からtrueへの割り当てに渡されます。あなたは、オプションとしてassignmentTestingを宣言したが、AssignmentPrecedenceグループに++=を中置ない場合

  • は、コンパイラはassignmentTesting?.number += 3として声明を取るだろう。 (assignmentTesting?.number)nilを返すかどうかは分かりません。したがって、コンパイルに失敗します。あなたはAssignmentPrecedenceグループではオプション、および中置++=としてassignmentTestingを宣言すると

  • 、それはassignmentTesting?.number += 3はSE-0077に基づいてassignmentTesting?(.number += 3)として動作することができます。コンパイル時に型チェックされ、正しいことが証明されます。この文は、number += 3がオプションの連鎖よりも優先されるため、合格します。

  • assignmentTestingをアンラップすると、文はassignmentTesting!.number += 3になります。 assignmentTestingnilにならないと確信しているので、コンパイラは不平を言っていません。ただし、実行中にassignmentTestingがラップ解除されないと、実行時エラーが発生します。

+0

私はこれをすべて知っています。あなたの答えは何が起こるか説明していません。 –

+0

私はあなたのサンプルをしばらく試して遊んでいましたが、答えを出す前にあなたと@OOPerの会話を読んで、冗長であると思っていましたが、とにかく私の答えを更新しました。なぜそれがまだあなたに多くのことを気にかけているのか分かりませんが、あなたがまだ残っている場合には、申し訳ありませんが、私は助けませんでした。他の人がもっと説明をするかもしれません。 – Lawliet

関連する問題