( Swift 2.x )
Sie können das Array auch so erweitern, dass es einem Protokoll entspricht, das Blue-Rpints für generische Typmethoden enthält, z. B. ein Protokoll, das Ihre benutzerdefinierten funktionalen Dienstprogramme für alle generischen Array-Elemente enthält, die einer Typbeschränkung entsprechen, z. B. Protokoll MyTypes
. Der Vorteil dieses Ansatzes besteht darin, dass Sie Funktionen mit generischen Array-Argumenten schreiben können, mit der Einschränkung, dass diese Array-Argumente Ihrem Protokoll für benutzerdefinierte Funktionsdienstprogramme entsprechen müssen, z MyFunctionalUtils
. B. Protokoll .
Sie können dieses Verhalten entweder implizit erhalten, indem Sie die Array-Elemente auf "Typ" beschränken MyTypes
, oder - wie ich in der unten beschriebenen Methode zeigen werde - ganz klar und explizit, indem Sie den Header Ihrer generischen Array-Funktionen diese Eingabearrays direkt anzeigen lassen entspricht MyFunctionalUtils
.
Wir beginnen mit Protokollen MyTypes
zur Verwendung als Typeinschränkung. die Typen erweitern Sie dieses Protokoll in Ihrem Generika passen wollen (Beispiel erstreckt sich unter Grundtypen Int
und Double
sowie einen benutzerdefinierten Typ MyCustomType
)
/* Used as type constraint for Generator.Element */
protocol MyTypes {
var intValue: Int { get }
init(_ value: Int)
func *(lhs: Self, rhs: Self) -> Self
func +=(inout lhs: Self, rhs: Self)
}
extension Int : MyTypes { var intValue: Int { return self } }
extension Double : MyTypes { var intValue: Int { return Int(self) } }
// ...
/* Custom type conforming to MyTypes type constraint */
struct MyCustomType : MyTypes {
var myInt : Int? = 0
var intValue: Int {
return myInt ?? 0
}
init(_ value: Int) {
myInt = value
}
}
func *(lhs: MyCustomType, rhs: MyCustomType) -> MyCustomType {
return MyCustomType(lhs.intValue * rhs.intValue)
}
func +=(inout lhs: MyCustomType, rhs: MyCustomType) {
lhs.myInt = (lhs.myInt ?? 0) + (rhs.myInt ?? 0)
}
Protokoll MyFunctionalUtils
(enthält Blaupausen unserer zusätzlichen Dienstprogramme für generische Array-Funktionen) und danach die Erweiterung von Array um MyFunctionalUtils
; Implementierung von Blaupausenverfahren:
/* Protocol holding our function utilities, to be used as extension
o Array: blueprints for utility methods where Generator.Element
is constrained to MyTypes */
protocol MyFunctionalUtils {
func foo<T: MyTypes>(a: [T]) -> Int?
// ...
}
/* Extend array by protocol MyFunctionalUtils and implement blue-prints
therein for conformance */
extension Array : MyFunctionalUtils {
func foo<T: MyTypes>(a: [T]) -> Int? {
/* [T] is Self? proceed, otherwise return nil */
if let b = self.first {
if b is T && self.count == a.count {
var myMultSum: T = T(0)
for (i, sElem) in self.enumerate() {
myMultSum += (sElem as! T) * a[i]
}
return myMultSum.intValue
}
}
return nil
}
}
Schließlich Tests und zwei Beispiele, die eine Funktion zeigen, die generische Arrays mit den folgenden Fällen verwendet
Zeigen der impliziten Behauptung, dass die Array-Parameter dem Protokoll 'MyFunctionalUtils' entsprechen, über einen Typ, der die Arrays-Elemente auf 'MyTypes' (Funktion bar1
) beschränkt.
Es wird explizit angezeigt, dass die Array-Parameter dem Protokoll 'MyFunctionalUtils' (Funktion bar2
) entsprechen.
Der Test und die Beispiele folgen:
/* Tests & examples */
let arr1d : [Double] = [1.0, 2.0, 3.0]
let arr2d : [Double] = [-3.0, -2.0, 1.0]
let arr1my : [MyCustomType] = [MyCustomType(1), MyCustomType(2), MyCustomType(3)]
let arr2my : [MyCustomType] = [MyCustomType(-3), MyCustomType(-2), MyCustomType(1)]
/* constrain array elements to MyTypes, hence _implicitly_ constraining
array parameters to protocol MyFunctionalUtils. However, this
conformance is not apparent just by looking at the function signature... */
func bar1<U: MyTypes> (arr1: [U], _ arr2: [U]) -> Int? {
return arr1.foo(arr2)
}
let myInt1d = bar1(arr1d, arr2d) // -4, OK
let myInt1my = bar1(arr1my, arr2my) // -4, OK
/* constrain the array itself to protocol MyFunctionalUtils; here, we
see directly in the function signature that conformance to
MyFunctionalUtils is given for valid array parameters */
func bar2<T: MyTypes, U: protocol<MyFunctionalUtils, _ArrayType> where U.Generator.Element == T> (arr1: U, _ arr2: U) -> Int? {
// OK, type U behaves as array type with elements T (=MyTypes)
var a = arr1
var b = arr2
a.append(T(2)) // add 2*7 to multsum
b.append(T(7))
return a.foo(Array(b))
/* Ok! */
}
let myInt2d = bar2(arr1d, arr2d) // 10, OK
let myInt2my = bar2(arr1my, arr2my) // 10, OK
extension T[]
Bit wird angezeigt, wenn Sie bei gedrückter Befehlstaste auf den Array-Typ in XCode klicken, aber keine Möglichkeit sehen, ihn ohne Fehler zu implementieren.