( Swift 2.x )
Anda juga dapat memperluas array agar sesuai dengan protokol yang mengandung blue-rpints untuk metode tipe generik, misalnya, protokol yang berisi utilitas fungsional kustom Anda untuk semua elemen array generik yang sesuai dengan beberapa batasan tipe, misalnya protokol MyTypes. Bonus menggunakan pendekatan ini adalah bahwa Anda dapat menulis fungsi yang mengambil argumen array umum, dengan batasan bahwa argumen array ini harus sesuai dengan protokol utilitas fungsi kustom Anda, misalnya protokolMyFunctionalUtils .
Anda bisa mendapatkan perilaku ini baik secara implisit, dengan mengetik membatasi elemen array MyTypes, atau --- seperti yang akan saya tunjukkan dalam metode yang saya jelaskan di bawah ---, cukup rapi, secara eksplisit, membiarkan tajuk fungsi array generik Anda secara langsung menunjukkan bahwa input array sesuai dengan MyFunctionalUtils.
Kita mulai dengan Protokol MyTypesuntuk digunakan sebagai batasan tipe; memperpanjang jenis yang ingin Anda muat dalam obat generik Anda dengan protokol ini (contoh di bawah ini memperluas jenis dasar Intdan Doublejuga jenis khusus 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(memegang cetak biru utilitas fungsi array generik tambahan kami) dan setelah itu, perpanjangan Array oleh MyFunctionalUtils; implementasi metode cetak biru:
/* 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
}
}
Akhirnya, tes dan dua contoh menunjukkan fungsi mengambil array generik, dengan kasus-kasus berikut, masing-masing
Menampilkan pernyataan implisit bahwa parameter array sesuai dengan protokol 'MyFunctionalUtils', melalui tipe yang membatasi elemen array ke 'MyTypes' (fungsi bar1).
Menunjukkan secara eksplisit bahwa parameter array sesuai dengan protokol 'MyFunctionalUtils' (fungsi bar2).
Tes dan contoh berikut:
/* 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 yang sama ketika mengklik perintah pada jenis Array di XCode, tetapi tidak melihat cara untuk mengimplementasikannya tanpa mendapatkan kesalahan.