配列の要素に循環的にアクセスしようとして%演算子でハマった点について書き残します。
%演算が負になる例
Swiftでは%演算の結果が必ずしも正になるとは限りません。負の数に対して%演算すると負の数になります。
5 % 3 == 2 //true
-4 % 3 == 2 //false
-4 % 3 == -1 // true
この結果、例えば次のようなコードはエラーになります。
let array = [1, 2, 3]
array[-1 % array.count] // Fatal error: Index out of range
%演算の結果は剰余ではない
The Swift Programming Language (Swift 4.1): Basic Operatorsに記述があり、remainder
演算であってmodulo
演算でない旨がNoteとして明記されています。
The remainder operator (%) is also known as a modulo operator in other languages. However, its behavior in Swift for negative numbers means that, strictly speaking, it’s a remainder rather than a modulo operation.
解決策
%演算を用いてmodulo
演算の結果は次のように得られます。
((-4 % 3) + 3) % 3 == 2 // true
独自演算子を定義する場合、例えば次のように剰余を得る演算子 %%
を定義できます。
infix operator %%
func %%(lhs: Int, rhs: Int) -> Int{
return ((lhs % rhs) + rhs) % rhs
}
(-4 %% 3) == 2 // true