Generic (pemrograman generik) — adalah mekanisme Swift yang memungkinkan penulisan tipe dan fungsi dengan tipe terparameterisasi
Poin Utama
Generic (tipe generik) — adalah konstruksi sintaksis Swift yang memungkinkan penulisan kode yang fleksibel dan dapat digunakan kembali dengan parameterisasi tipe. Alih-alih tipe konkret, placeholder ditulis dalam tanda kurung siku — biasanya
Tanpa generik, fungsi terpisah harus ditulis untuk setiap tipe: swapInts, swapStrings, swapDates. Fungsi generik swap menggantikan ketiga varian dengan satu deklarasi. Ini mengurangi duplikasi, meningkatkan keterbacaan, dan mengurangi kemungkinan kesalahan saat menyalin kode.
func swapValues<T>(_ a: inout T, _ b: inout T) {
let temp = a
a = b
b = temp
}
var x = 10
var y = 20
swapValues(&x, &y)
Kompiler Swift menghasilkan kode terspesialisasi untuk setiap penggunaan generik yang konkret. Ini berarti fungsi generik swapValues
Fungsi generik — adalah fungsi yang menerima satu atau lebih parameter-tipe. Parameter-tipe ditunjukkan setelah nama fungsi dalam tanda kurung siku:
Sebuah fungsi dapat memiliki beberapa parameter generik. Misalnya, fungsi findKey
func findKey<K: Hashable, V>(
for value: V,
in dictionary: [K: V]
) -> K? where V: Equatable {
for (key, dictValue) in dictionary {
if dictValue == value {
return key
}
}
return nil
}
Batasan K: Hashable dan where V: Equatable menjamin bahwa findKey hanya dapat dipanggil dengan kamus yang kuncinya dapat di-hash dan nilainya dapat dibandingkan. Batasan semacam itu bukan birokrasi, tetapi kebutuhan: tanpa Hashable, pencarian berdasarkan kunci tidak dapat diindeks, tanpa Equatable, value tidak dapat dibandingkan dengan dictValue.
where — adalah kata kunci Swift yang memberlakukan batasan tambahan pada parameter generik. Tidak seperti penentuan protokol sederhana dalam tanda kurung siku (
Klausa where ditulis setelah tanda tangan fungsi atau tipe, sebelum kurung kurawal pembuka. Dalam where dapat ditentukan bahwa T: Comparable & Hashable (dua protokol sekaligus), atau bahwa T.U == Int (konkretisasi associated type).
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int { get }
}
extension Container where Item: Comparable {
func isSorted() -> Bool {
// Implementation available only if Item: Comparable
return true
}
}
Ekstensi dengan where menambahkan metode hanya untuk tipe-tipe yang memenuhi kondisi. Container
Associated Types (tipe terkait) — adalah cara untuk membuat protokol menjadi generik tanpa menentukan tipe konkret pada fase deklarasi. Alih-alih
Dengan where, hubungan dapat dibuat antara associated types dari protokol yang berbeda. Misalnya, dapat diharuskan bahwa Item dari satu protokol cocok dengan Iterator.Element dari protokol lain. Ini menjamin kompatibilitas tipe pada tingkat kompilasi.
protocol StackProtocol {
associatedtype Element
mutating func push(_ item: Element)
mutating func pop() -> Element?
}
struct IntStack: StackProtocol {
typealias Element = Int
private var items: [Int] = []
mutating func push(_ item: Int) { items.append(item) }
mutating func pop() -> Int? { items.popLast() }
}
IntStack mengkonkretisasi Element sebagai Int, menggunakan typealias. Kompiler memeriksa apakah semua persyaratan protokol terpenuhi dengan tipe ini. Tanpa associated types, StackProtocol
Ekstensi generik memungkinkan penambahan metode ke tipe generik dengan batasan tambahan. Ini adalah pola “konformitas bersyarat”, ketika tipe mendapatkan fungsionalitas hanya dalam kondisi tertentu. Subscript juga bisa bersifat generik.
Subscript dapat bersifat generik: ia menerima parameter generik dalam tanda kurung siku. Ini berguna untuk akses aman ke koleksi dengan indeks arbitrer, ketika indeks dapat berupa tipe yang berbeda.
extension Array where Element: Numeric {
func sum() -> Element {
return reduce(0, +)
}
}
extension Array {
subscript<Indices: Sequence>(indices: Indices) -> [Element]
where Indices.Element == Int {
return indices.map { self[$0] }
}
}
Konstruksi semacam itu memberikan komposisi yang kuat: metode sum muncul hanya di array numerik, dan subscript dengan indeks arbitrer bekerja dengan sekuens indeks bilangan bulat apa pun. Kompiler sendiri mengelola visibilitas anggota-anggota ini berdasarkan kondisi where.
Kesalahan saat menggunakan generik sering terkait dengan batasan yang salah atau upaya menggunakan generik di mana tipe konkret diperlukan. Mari kita lihat tiga skenario umum yang dihadapi pengembang.
Menambahkan parameter generik di mana tipe konkret sudah cukup — adalah anti-pola. Jika suatu fungsi selalu bekerja dengan String, tidak perlu membuatnya
Memanggil metode pada parameter generik tanpa menentukan bahwa metode tersebut ada — adalah kesalahan.
// ❌ Error: value has no count method
func countElements<T>>(value: T) -> Int { value.count }
// ✅ Works: T: Collection guarantees count exists
func countElements<T: Collection>(value: T) -> Int { value.count }
Kesalahannya dapat dimengerti: generik
Pertanyaan yang Sering Diajukan
Generic — adalah cara menulis kode yang bekerja dengan tipe apa pun, tanpa menduplikasi logika yang sama untuk Int, String, dan tipe lainnya. Alih-alih tipe konkret, placeholder
Generic menyimpan informasi tentang tipe konkret pada fase kompilasi, yang memungkinkan kompiler memeriksa tipe dan menghasilkan kode yang dioptimalkan. Any — adalah penghapusan tipe: nilai apa pun dapat diteruskan, tetapi tipe hilang dan diperlukan konversi (as?).
Gunakan sintaks T: SomeProtocol dalam tanda kurung siku atau klausa terpisah where T: SomeProtocol. Batasan menjamin bahwa parameter generik mendukung metode dan properti tertentu.
Associated Type (associatedtype) — adalah placeholder untuk tipe di dalam protokol. Protokol tidak menentukan tipe konkret, tetapi mendeklarasikan associatedtype yang dikonkretisasi dalam implementasi: Array memiliki Element, Dictionary — Key dan Value.
Swift mengkompilasi kode generik menjadi versi terspesialisasi untuk setiap tipe konkret. Dalam praktiknya, fungsi generik untuk Int tidak lebih lambat dari fungsi yang ditulis manual untuk Int. Tidak ada overhead untuk abstraksi.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga