サーチ…


カスタム演算子

Swiftは、カスタム演算子の作成をサポートしています。新しい演算子はoperatorキーワードを使用してグローバルレベルで宣言されます。

オペレータの構造は、オペランドの配置、優先順位、および結合性の3つの部分で定義されます。

  1. prefixinfixpostfix修飾は、カスタム演算子宣言を開始するために使用されています。 prefixpostfix修飾子は、演算子が動作する前の値であるか、後であるかを宣言します。このような演算子は、1つのターゲットに対してのみ動作できるため、 8および3++ **のようなurnaryです。 infix 、バイナリ演算子を宣言します。バイナリ演算子は、 2+3などの2つの値に作用します。

  2. 優先順位の高い演算子が最初に計算されます。デフォルトの演算子の優先順位は、より高いです? ... : Swift 2.xでは100の値)。標準的なSwift演算子の優先順位はここで見つけることができます

  3. Associativityは、同じ優先順位の演算子間の演算の順序を定義します。左連想演算子は、左から右(ほとんどの演算子のように読取り順序)で計算され、右結合演算子は右から左に計算されます。

3.0

Swift 3.0からは、演算子自体ではなく優先順位グループ内で優先順位と結合を定義することで、複数の演算子が潜在的な数値を参照することなく簡単に同じ優先順位を共有できるようになります。標準優先グループのリストを以下に示します

演算子は、計算コードに基づいて値を返します。このコードは、入力のタイプを指定するパラメータと、演算子が返す計算値を指定するreturnキーワードを持つ通常の関数として機能します。

標準スウィフトには指数演算子がないため、単純指数演算子の定義があります。

import Foundation    

infix operator ** { associativity left precedence 170 }

func ** (num: Double, power: Double) -> Double{
    return pow(num, power)
}

infixは、 **演算子は9**2ように2つの値の間で動作すると言います。関数は連想を残しているので、 3**3**2(3**3)**2として計算されます。優先順位170つまり、すべての標準スウィフト操作よりも高い3+2**4に算出19の左側の結合性にもかかわらず、 **

3.0
import Foundation 

infix operator **: BitwiseShiftPrecedence

func ** (num: Double, power: Double) -> Double {
    return pow(num, power)
}

優先度と結合性を明示的に指定するのではなく、Swift 3.0では、正しい値( <<>>と同じ)を与えるビルトイン優先グループBitwiseShiftPrecedenceを使用できます。

**:インクリメントとデクリメントは廃止され、Swift 3では削除されます。

辞書のオーバーロード+

現在のところSwiftで辞書を組み合わせる簡単な方法はないので、 ジェネリックを使ってこの機能を追加するには、 ++=演算子をオーバーロードすると便利です。

// Combines two dictionaries together. If both dictionaries contain
// the same key, the value of the right hand side dictionary is used.
func +<K, V>(lhs: [K : V], rhs: [K : V]) -> [K : V] {
    var combined = lhs
    for (key, value) in rhs {
        combined[key] = value
    }
    return combined
}

// The mutable variant of the + overload, allowing a dictionary
// to be appended to 'in-place'.
func +=<K, V>(inout lhs: [K : V], rhs: [K : V]) {
    for (key, value) in rhs {
        lhs[key] = value
    }
}
3.0

スイフト3の時点では、 inoutは引数の型の前に置く必要があります。

func +=<K, V>(lhs: inout [K : V], rhs: [K : V]) { ... } 

使用例:

let firstDict = ["hello" : "world"]
let secondDict = ["world" : "hello"]
var thirdDict = firstDict + secondDict // ["hello": "world", "world": "hello"]

thirdDict += ["hello":"bar", "baz":"qux"] // ["hello": "bar", "baz": "qux", "world": "hello"]

可換演算子

CGSizeを乗算するカスタム演算子を追加しましょう

func *(lhs: CGFloat, rhs: CGSize) -> CGSize{
    let height = lhs*rhs.height
    let width = lhs*rhs.width
    return CGSize(width: width, height: height)
}

今これは動作します

let sizeA = CGSize(height:100, width:200)    
let sizeB = 1.1 * sizeA         //=> (height: 110, width: 220)

しかし、逆に操作しようとすると、エラーが発生します

let sizeC = sizeB * 20          // ERROR

しかし、追加するだけで十分です:

func *(lhs: CGSize, rhs: CGFloat) -> CGSize{
    return rhs*lhs
}

オペレータは可換性です。

let sizeA = CGSize(height:100, width:200)    
let sizeB = sizeA * 1.1              //=> (height: 110, width: 220)

ビット演算子

Swift Bitwise演算子を使用すると、バイナリ形式の数値に対して演算を実行できます。数字の先頭に0b付けることで、バイナリリテラルを指定することができます。たとえば、 0b110は2進数110(10進数6)と等価です。それぞれ1または0は数字のビットです。

ビットごとのNOT ~

var number: UInt8 = 0b01101100
let newNumber = ~number
// newNumber is equal to 0b01101100

ここでは、各ビットがその反対に変更されます。明示的に番号を宣言UInt8数が正である(私たちは例のネガに対処する必要がないように)、それは唯一の8ビットであることを保証します。 0b01101100がより大きい0b01101100だった場合、先頭に0があり、これは1に変換され、反転時に有意になります。

var number: UInt16 = 0b01101100
// number equals 0b0000000001101100
// the 0s are not significant
let newNumber = ~number
// newNumber equals 0b1111111110010011
// the 1s are now significant
  • 0 - > 1
  • 1→0

ビット単位AND &

var number = 0b0110
let newNumber = number & 0b1010
// newNumber is equal to 0b0010

ここで、 &演算子の両側の2進数がそのビット位置に1を含む場合に限り、与えられたビットは1になります。

  • 0&0 - > 0
  • 0&1→0
  • 1&1→1

ビット単位OR |

var number = 0b0110
let newNumber = number | 0b1000
// newNumber is equal to 0b1110

ここで、 | 1の少なくとも片側の2進数が1である場合に限り、与えられたビットは1になります|オペレータはそのビット位置に1を含んでいた。

  • 0 | 0→0
  • 0 | 1→1
  • 1 | 1→1

ビット単位の排他的論理和(排他的論理和) ^

var number = 0b0110
let newNumber = number ^ 0b1010
// newNumber is equal to 0b1100

ここで、2つのオペランドのその位置にあるビットが異なる場合に限り、与えられたビットは1になります。

  • 0 ^ 0→0
  • 0 ^ 1→1
  • 1 ^ 1→0

すべてのバイナリ演算では、オペランドの順序が結果に大きな違いはありません。

オーバーフロー演算子

オーバーフローとは、操作によって、指定された数のビットが保持できるビット数よりも大きいか小さいビット数になる場合に発生することを指します。

バイナリ算術が動作する方法のために、あるビットがそのビットに対して大きすぎると、その数は(ビット・サイズのために)可能な限り小さい数にオーバーフローし、そこからカウント・アップを続ける。同様に、数値が小さ過ぎると、可能な限り最大数(ビットサイズ)までアンダーフローし、そこからカウントダウンを続けます。

この動作はしばしば望ましくなく、重大なセキュリティ問題につながる可能性があるため、操作がオーバーフローまたはアンダーフローを引き起こすと、Swift算術演算子+- 、および*はエラーをスローします。オーバーフローとアンダーフローを明示的に許可するには、代わりに&+&-&*使用します。

var almostTooLarge = Int.max
almostTooLarge + 1 // not allowed
almostTooLarge &+ 1 // allowed, but result will be the value of Int.min

標準Swiftオペレータの優先順位

より緊密に(高い優先順位)バインドされた演算子が最初にリストされます。

演算子優先グループ(≧3.0) 優先順位関連性
.
?!++--[](){} (後置)
!~+-++-- (接頭辞)
~> (速い≤2.3) 255
<<>> BitwiseShiftPrecedence 160 無し
*/%&&* MultiplicationPrecedence 150
+-|^&+&- AdditionPrecedence 140
.....< RangeFormationPrecedence 135 無し
isasas?as! CastingPrecedence 132
?? NilCoalescingPrecedence 131
<<=>>===!====!==~= ComparisonPrecedence 130 無し
&& LogicalConjunctionPrecedence 120
|| LogicalDisjunctionPrecedence 110
DefaultPrecedence * 無し
? ... : TernaryPrecedence 100
=+=-=*=/=%=<<=>>=&=|=^= AssignmentPrecedence 90 権利、譲渡
-> FunctionArrowPrecedence
3.0
  • DefaultPrecedence優先順位グループはTernaryPrecedenceよりも上位ですが、残りの演算子と順序はTernaryPrecedenceます。このグループ以外の優先順位は線形です。


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow