0Pricing
Kotlin Academy · Lekcja

Najlepsze praktyki

Zachowuj intuicyjność operatorów

Najlepsze praktyki to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Zachowuj intuicyjne operatory

Przeciążaj operator tylko wtedy, gdy jego znaczenie jest oczywiste. + dla wektorów jest zrozumiały, ale + oznaczający wysłanie wiadomości e-mail już nie.

data class Vec(val x: Int, val y: Int) {
    operator fun plus(o: Vec) = Vec(x + o.x, y + o.y)
}

fun main() {
    println(Vec(1, 2) + Vec(3, 4))
}

Zachowuj oczekiwaną semantykę

Przestrzegaj zwykłych praw algebry: dla typów symetrycznych wyrażenie a + b powinno sprawiać wrażenie przemiennego i nie zaskakiwać czytających.

data class Money(val cents: Int) {
    operator fun plus(o: Money) = Money(cents + o.cents)
}

fun main() {
    println(Money(100) + Money(50))
}

Preferuj niezmienność

Operatory takie jak plus powinny zwracać nową wartość zamiast modyfikować odbiorcę, zgodnie z zachowaniem liczb.

data class Point(val x: Int) {
    operator fun plus(o: Point) = Point(x + o.x)
}

fun main() {
    val a = Point(1)
    val b = a + Point(2)
    println("${a.x} ${b.x}")
}

plus a plusAssign

Definiuj plus dla wartości niezmiennych, a plusAssign dla modyfikowania zawartości mutowalnych kontenerów. Unikaj definiowania obu operatorów z niespójnym zachowaniem.

class Cart {
    val items = mutableListOf<String>()
    operator fun plusAssign(item: String) { items.add(item) }
}

fun main() {
    val c = Cart()
    c += "book"
    println(c.items)
}

Dopasowuj typy zwracane

Operatory dwuargumentowe powinny zwracać ten sam typ, aby wyniki można było naturalnie łączyć w łańcuchy.

data class N(val v: Int) {
    operator fun plus(o: N) = N(v + o.v)
}

fun main() {
    println((N(1) + N(2) + N(3)).v)
}

Nie przeciążaj dla efektu

Jeśli lepiej sprawdzi się nazwana funkcja, użyj jej. Operatory służą do wyrażania rzeczywiście liczbowej semantyki lub semantyki podobnej do kontenerów, a nie do tworzenia zagadek.

data class Log(val lines: List<String>) {
    fun append(line: String) = Log(lines + line)
}

fun main() {
    println(Log(emptyList()).append("start").lines)
}

Zachowuj spójność equals i hashCode

Jeśli przeciążasz porównywanie lub równość, zachowaj spójność między equals i hashCode, aby uniknąć problemów z kolekcjami.

data class Id(val v: Int)

fun main() {
    val set = hashSetOf(Id(1), Id(1))
    println(set.size)
}

Zwracaj uwagę na priorytet operatorów

Przeciążone operatory zachowują wbudowany priorytet. Projektuj je tak, aby naturalny priorytet dawał oczekiwane wyniki.

data class N(val v: Int) {
    operator fun plus(o: N) = N(v + o.v)
    operator fun times(o: N) = N(v * o.v)
}

fun main() {
    println((N(2) + N(3) * N(4)).v)
}

Dokumentuj zaskakujące operatory

Jeśli operator wykonuje coś nieoczywistego, dodaj komentarz lub KDoc, aby nie wprowadzać wywołujących w błąd.

data class Range2(val start: Int, val end: Int) {
    // contains: is value inside the range?
    operator fun contains(v: Int) = v in start..end
}

fun main() {
    println(5 in Range2(1, 10))
}

Używaj contains dla in

Operator in jest mapowany na contains. Przeciążaj go tylko wtedy, gdy przynależność jest dobrze zdefiniowana dla danego typu.

class Team(val members: List<String>) {
    operator fun contains(name: String) = name in members
}

fun main() {
    val t = Team(listOf("Ann", "Bo"))
    println("Ann" in t)
}

W razie wątpliwości użyj funkcji

Jasno nazwana metoda jest niemal zawsze bezpieczniejsza niż nieoczywisty operator. Przeciążanie warto stosować tylko wtedy, gdy rzeczywiście poprawia czytelność.

data class Temperature(val c: Int) {
    fun warmerThan(o: Temperature) = c > o.c
}

fun main() {
    println(Temperature(30).warmerThan(Temperature(20)))
}

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat dobrych praktyk przeciążania operatorów.

Podsumowanie

Opanowali Państwo dobre praktyki przeciążania operatorów:

  • Przeciążaj operatory tylko wtedy, gdy ich znaczenie jest oczywiste i zgodne z konwencją.
  • Preferuj niezmienne wartości i zwracanie tego samego typu; zachowuj możliwość łączenia wyników w łańcuchy.
  • Rozdziel plus (wartość) od plusAssign (modyfikowanie).
  • Zachowuj spójność equals/hashCode; gdy jest to czytelniejsze, preferuj nazwane funkcje.
data class V(val x: Int) {
    operator fun plus(o: V) = V(x + o.x)
}

fun main() {
    println((V(2) + V(5)).x)
}

Często zadawane pytania

Czy lekcja „Najlepsze praktyki” jest bezpłatna?

Tak — pełny tekst „Najlepsze praktyki” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Najlepsze praktyki”?

Zachowuj intuicyjność operatorów Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?

Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Najlepsze praktyki”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?

Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Funkcje operatorowe
  2. Operatory porównania
  3. Indeksowanie i invoke
  4. Najlepsze praktyki
← Powrót do Kotlin Academy