Generic dalam swift


Artikel kali ini kita akan membahas tentang pengenalan generic dalam swift. Ketika kamu mendengar kata generic anda mungkin berfikir generic itu berarti serbaguna.

Silahkan buka playground. Kemudian buat beberapa element array.

let highSchoolGPA = [2.8, 3.2, 3.5, 3.8, 3.5]
let favoritePeople = ["Elon Musk", "Steve Jobs", "Kevin O'leary"]
let favoriteNumbers = [3, 20]

Berikut cara paling buruk dalam mengakses element

highSchoolGPA[0]
highSchoolGPA[1]
highSchoolGPA[2]

Loop dan Print

Cara ini sedikit lebih baik

func printDoubleElement(array: [Double]) {
  for GPA in array {
    print(GPA)
  }
}

func printStringElement(array: [String]) {
  for person in array {
    print("I love \(person)")
  }
}

func printNumberElement(array: [Int]) {
  for number in array {
    print("I like \(number)")
  }
}

Banyak fungsi yang tidak perlu. Ini bertentangan dengan prinsip DRY (Don’t Repeat Yourself)

Generic

Fungsi generik memungkinkan Kamu untuk memberikan nilai apa pun terlepas dari jenisnya.

func genericFunction<anything>(value: anything) {
  print(value)
}

func genericFunctions<WHATEVER>(value: WHATEVER) {
  print(value)
}

Swift menyimpulkan tipe anything atau WHATEVER berdasarkan input.

genericFunction(value: "Bob")  // anything is String
genericFunctions(value: true)  // WHATEVER is Bool

Generic Loop

func printElement<T>(array: [T]) {
  for element in array {
    print(element)
  }
}

Cara memanggil fungsi

printElement(array: highSchoolGPA) // 2.8, 3.2, 3.5, ...
printElement(array: favoritePeople) // 'Elon Musk", "Steve Jobs", ...

Kode generik memungkinkan Kamu menulis function, class, enum, protocol, dan struct yang fleksibel, dapat digunakan kembali, sesuai dengan persyaratan yang Kamu tetapkan.

Sekarang Kamu tidak hanya sudah bisa membuat fungsi generik, tetapi juga class dan struct generik. Mari kita mulai dengan struct non-generik.

Non-Generic Struct

Buatlah struct Family yang memiliki members yang bertipe [string]. Tambahkan fungsi untuk append data kedalam array tersebut.

struct Family {
  var members = [String]()

  mutating func push(member: String) {
    members.append(member)
  }
}

Penting: Kata kunci mutating ditambahkan ke fungsi enum atau struct yang mengubah properti-properti dirinya sendiri.

Non-Generic Instance

var myFam = Family()
myFam.push(member: "Bob")
myFam.members // ["Bob"]

Struct di atas hanya bekerja dengan String. Jika Beberapa family mungkin memiliki nama mengandung Int. Kemudian, Kamu harus membuat struct baru dan jadi sangat merepotkan karena bisa terjadi redudansi. Itu bertentangan dengan prinsip DRY.

Generic Struct

struct genericFam<T> {
  var members = [T]()

  mutating func push(member: T) {
    members.append(member)
  }
}

Sebelumnya kita menggunakan WHATEVER atau anything untuk menyimbolkan generic, namun T adalah standar untuk developer iOS.

Mendefinisikan Tipe Secara Explisit

Sekarang mari kita buat sebuah object dari struct generik. Kamu harus menentukan tipe berdasarkan aturan dalam artikel sebelumnya optional dalam swift.

var myGenericFamily = genericFam<String>()
myGenericFamily.push(member: "Bobby")

var genericFamily = genericFam<Int>()
genericFamily.push(member: 123)

Mendefinisikan Tipe Secara Implisit

Tipe dapat disimpulkan berdasarkan input.

let myHappyFamily = genericFam(members: [1, 2, 3, 4, 5])  // T menjadi [Int]

Generic Extension

Kamu dapat menambahkan ekstensi ke generik untuk lebih banyak fitur. Sebagai contoh mari kita ambil elemen pertama di properti members.

extension genericFam {
  var firstElement: T? {
    if members.isEmpty {
      return nil
    } else {
      return members[0]
    }
  }
}

let geekFamilyMember = genericFam(members: ["Bob", "Bobby"])
let firstElement = geekFamilyMember.firstElement // "Bob"

Type Constraints

Sejauh ini, Kamu dapat memasukkan nilai apa pun untuk mendefinisikan T. Tapi, Kamu juga dapat membatasi tipe sesuai kebutuhan Kamu.

Pertama, kita buat 2 class.

class LOL {}
class BabyLol: LOL {}

Sekarang kita buat sebuah fungsi yang hanya memperbolehkan kamu memasukkan LOL.

func addLOLClassOnly<T: LOL>(array: [T]) { }

Ketika Kamu menjalankan fungsi addLOLClassOnly, Kamu tidak dapat menambahkan apapun selain yang bertipe LOL.

addLOLClassOnly(array: [LOL(), LOL(), LOL(), BabyLol()])
addLOLClassOnly(array: [1, 2, 3, 4, 5]) // Error

Penting:BabyLol() otomatis di upcasting ke LOL.

Sekian pengenalan tentang generik dalam swift, semoga bermanfaat.

0 0 votes
Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

0
Would love your thoughts, please comment.x
()
x