( Hızlı 2.x )
Ayrıca diziyi, genel yazım yöntemleri için mavi rpint içeren bir protokole uyacak şekilde genişletebilirsiniz; örneğin, bir tür kısıtlamasına uygun tüm genel dizi elemanları için özel fonksiyonel araçlarınızı içeren bir protokol, örneğin protokol MyTypes
. Bu yaklaşımı kullanarak bonus, genel dizi bağımsız değişkenleri alan işlevler yazabilmenizdir, bu dizi bağımsız değişkenlerinin özel işlev yardımcı programları protokolünüze uyması gereken bir kısıtla, örneğin protokol MyFunctionalUtils
.
Bu davranışı örtülü olarak, dizi öğelerini sınırlandırarak yazarak MyTypes
veya --- aşağıda açıkladığım yöntemde göstereceğim gibi ---, oldukça düzgün, açık bir şekilde, genel dizi işlevlerinizin üstbilginin doğrudan giriş dizilerini göstermesine izin vererek uygun MyFunctionalUtils
.
MyTypes
Tip kısıtı olarak kullanılacak Protokollerle başlıyoruz ; bu protokolle jeneriklerinize uymak istediğiniz türleri genişletin (aşağıdaki örnek temel türleri Int
ve Double
özel bir türü genişletir 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)
}
Protokol MyFunctionalUtils
(ek jenerik dizi fonksiyonları yardımcı programlarımızın planlarını tutarak) ve daha sonra Array by uzantısını MyFunctionalUtils
; mavi baskılı yöntem (ler) in uygulanması:
/* 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
}
}
Son olarak, aşağıdaki durumlarda sırasıyla, genel dizileri alan bir işlevi gösteren testler ve iki örnek
Gösterilen örtük 'MyTypes' (işlev için diziler elemanları kısıtlayıcı türü yoluyla, dizi parametreleri protokolü 'MyFunctionalUtils' uygun olduğu iddiasını bar1
).
Gösterilen açıkça dizi parametreler 'MyFunctionalUtils' (işlev protokolüne uygun olmasını bar2
).
Test ve örnekler aşağıdaki gibidir:
/* 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[]
Array türüne Komut tıklatıldığında aynı biti görüyor, ancak hata almadan uygulamak için herhangi bir yol görmüyoruz.