Sobes.tech
Middle

Πώς να εργαστείτε με γενικούς τύπους στο Kotlin;

sobes.tech AI

Απάντηση από AI

Οι γενικοί τύποι στο Kotlin επιτρέπουν τη δημιουργία κλάσεων, διεπαφών και συναρτήσεων που λειτουργούν με δεδομένα διαφορετικών τύπων, διατηρώντας την ασφάλεια τύπων κατά τη διάρκεια της μεταγλώττισης.

Βασικές έννοιες και τρόποι εργασίας:

  • Δήλωση γενικών κλάσεων και διεπαφών:
    class Box<T>(val item: T) // Γενική κλάση με παράμετρο τύπου T
    interface MyList<E> { // Γενική διεπαφή με παράμετρο τύπου E
        fun add(element: E)
        fun get(index: Int): E
    }
    
  • Δήλωση γενικών συναρτήσεων:
    fun <T> printAnything(value: T) { // Γενική συνάρτηση με παράμετρο τύπου T
        println(value)
    }
    
  • Δημιουργία στιγμιοτύπων γενικών τύπων:
    val intBox: Box<Int> = Box(123) // Ορισμός συγκεκριμένου τύπου (Int)
    val stringBox = Box("hello") // Ο μεταγλωττιστής εμφανίζει τον τύπο (String)
    
  • Επιλογές: Επιτρέπει τον ορισμό του πώς λειτουργούν οι υποτύποι με τους γενικούς τύπους.
    • Κοβαριαντότητα (out): Επιτρέπει τη χρήση του τύπου και των υποτύπων του. Αναφέρεται ως out. Παράδειγμα: List<out Any> μπορεί να περιέχει List<String>. Χρησιμοποιείται για τύπους που παράγουν τιμές (π.χ. ανάγνωση από συλλογή).
      interface Producer<out T> { // out T - κοβαριαντό παράμετρος
           fun produce(): T
      }
      
    • Αντιδραστικότητα (in): Επιτρέπει τη χρήση του τύπου και των υπερτύπων του. Αναφέρεται ως in. Παράδειγμα: Comparator<in String> μπορεί να λειτουργεί με Comparator<Any>. Χρησιμοποιείται για τύπους που καταναλώνουν τιμές (π.χ. εγγραφή σε συλλογή).
      interface Consumer<in T> { // in T - αντιδραστική παράμετρος
          fun consume(value: T)
      }
      
    • Αντιπροσωπευτικότητα (Invariance): Ο τύπος στην γενική παράμετρο πρέπει να είναι ακριβώς ο ίδιος. Αυτή είναι η προεπιλεγμένη συμπεριφορά.
  • Περιορισμοί τύπων (where): Επιτρέπει τον περιορισμό του τύπου παραμέτρου ώστε να υλοποιεί συγκεκριμένες διεπαφές ή να κληρονομεί από συγκεκριμένη κλάση.
    fun <T : Comparable<T>> max(a: T, b: T): T { // T πρέπει να υλοποιεί το Comparable
        return if (a > b) a else b
    }
    
    fun <T> process(item: T) where T : Runnable, T : Comparable<T> {
        item.run()
        // ... χρησιμοποιούμε συγκρίσιμότητα
    }
    
  • Αστέρια (star) προβολή (*): Χρησιμοποιείται όταν δεν ενδιαφέρει ο συγκεκριμένος τύπος. Παρόμοιο με το <?> στη Java.
    fun printList(list: List<*>) { // Μπορεί να δεχτεί λίστα οποιουδήποτε τύπου
         for (item in list) {
             println(item)
         }
    }
    

Οι γενικοί τύποι στο Kotlin χρησιμοποιούν την αποσάθρωση τύπων (type erasure), όπως και στη Java. Οι πληροφορίες για συγκεκριμένους τύπους παραμέτρων χάνουν κατά τη διάρκεια της εκτέλεσης. Για εργασία με τύπους κατά τη διάρκεια της εκτέλεσης, χρησιμοποιούνται οι αναδιπλωμένοι (reified) τύποι.

  • Αναδιπλωμένοι τύποι (reified): Διαθέσιμοι μόνο σε inline συναρτήσεις. Επιτρέπουν τη διατήρηση πληροφοριών σχετικά με τον τύπο της παραμέτρου κατά τη διάρκεια της εκτέλεσης.
    inline fun <reified T> checkType(value: Any) { // T - αναδιπλωμένος τύπος
        if (value is T) {
            println("Value is of type T")
        } else {
            println("Value is not of type T")
        }
    }