問題は、プロトコルがオペレーターの存在をNumeric
保証していないことです。+=
このことを考慮:
// Numeric imposes no requirements, so this will compile
extension Range: Numeric { }
// but Range has no += operator, so +++ could not work
+=
代わりに、次の要件として追加する必要がありNumeric
ます。
protocol Numeric: IntegerLiteralConvertible {
func +=(inout lhs: Self,rhs: Self)
}
それに追加する適切なタイプの を作成できるように、 にもNumeric
準拠する必要があることに注意してください。IntegerLiteralConvertible
10
Numeric
これで、使用するすべての機能が利用可能になることが保証されるため、これは正常にコンパイルおよび実行されます。
prefix operator +++{}
prefix func +++<T: Numeric>(inout operand: T) -> T {
operand += 10
return operand
}
var i = 10
+++i // i is now 20
とは言っても、必要なことを行うプロトコルが既に存在します: Strideable
、すべての標準数値型が準拠しています。
protocol Strideable {
// (actually _Strideable but don’t worry about that)
/// A type that can represent the distance between two values of `Self`.
typealias Stride : SignedNumberType
// note, SignedNumberType conforms to IntegerLiteralConvertible
/// Returns a `Self` `x` such that `self.distanceTo(x)` approximates
/// `n`.
///
/// - Complexity: O(1).
///
/// - SeeAlso: `RandomAccessIndexType`'s `advancedBy`, which
/// provides a stronger semantic guarantee.
func advancedBy(n: Self.Stride) -> Self
}
そして、その実装は+=
それを使用します:
func +=<T : Strideable>(inout lhs: T, rhs: T.Stride)
+++
これは、次のように実装できることを意味します。
prefix func +++<T: Strideable>(inout operand: T) -> T {
operand = operand.advancedBy(10)
return operand
}