More

    A Kotlin-típusok megértése – Egység, Semmi, Bármely (és null)

    És hasonlókat is vonhat a Java-val 20215. február 18. perc52https: //d2xzmw6cctk25h.cloudfront.net/post/2552/og_image/c775b5c31db1dfd507bc5dfe763ec072.png

    Kotlin érdekes alaptípusokkal rendelkezik, amelyek némileg kapcsolódnak a Java-hoz. Ez az egység, semmi, semmi. Lássuk, melyek ezek az osztályok, miben különböznek (hasonló nevek ellenére), és hasonlítsuk össze őket Java-társaikkal. Beszéljünk még egy kicsit a nullról Kotlinban, mert ezek a témák összefüggenek.

    Mértékegység

    Az egység egyenértékű a Java-ban érvénytelennel. Ebben a kifejezésben a return típus elhagyható, ha a függvény nem ad semmit. Alapértelmezés szerint az Unit ott lesz:

     fun knockKnock () {println ("Ki van ott?")}

    Kotlinban kétféle módon lehet deklarálni egy függvényt: a módszer törzsében (göndör zárójelben) vagy kifejezésként (az egyenlőségjel használatával). Így átírhatja függvényünket, és megadhatja a visszatérési értéket:

     fun knockKnock (): Unit = println ("Ki van ott?")

    A szokásos Kotlin könyvtárban az egységet olyan objektumként definiálják, amely örököl mindeniktől, és egyetlen metódust tartalmaz, amely felülbírálja a

     public object Unit {override fun toString () = "kotlin.Unit"}

    Ügyeljen az objektum kulcsszavára. Ez azt jelenti, hogy az Unit egyedülálló. Az egység nem ad semmit, és a toString metódus mindig a „kotlin.Unit” értéket adja vissza. Java-kódra fordítva az Unit mindig érvénytelen lesz.

    Érdekes, hogy a Java-nak megvan a maga Void osztálya, amely meglehetősen gyenge, de mégis korrelál a voiddal és nem példázható. Ez egy pusztán haszonelvű osztály, amelyre szükség van a Java elmélkedéséhez és általános ismereteihez.

    Semmi

    Semmi sem sokkal érdekesebb. Semmi sem olyan osztály, amely Kotlin bármely osztályától örököl, még a végső módosítóval rendelkező osztálytól is. Semmit azonban nem lehet létrehozni – van privát konstruktora. A kódban ezt így deklarálják:

     nyilvános osztály Semmi magánépítő ()

    Mindezek ellenére a Semmi osztály elég hasznos. Mivel lehetetlen átadni vagy visszaküldeni a Semmi típust, leírja egy “funkció, amely soha nem ad vissza semmit” eredményét. Példaként szolgálhat egy olyan funkció, amely kivételt vet, vagy amelyben egy végtelen ciklust indítanak: mindkét esetben soha nem ad vissza értéket. Az alkalmazásokban, függetlenül attól, hogy milyen adattípust ad vissza a függvény, előfordulhat, hogy soha nem ad vissza adatokat, mert hiba történt, vagy a számítások végtelenségig késnek. Ebben az esetben van értelme a Semmit használni.

    Lássuk, hol használják ezt Kotlinban. Íme egy példa: a TODO () függvény, amelyet gyakran használnak csonkként az automatikusan létrehozott módszerekben.

     public inline fun TODO (): Semmi = dobás NotImplementedError ()

    A kód automatikus létrehozásakor a következő képet láthatja:

     felülírja a szórakoztató getData (szó: karakterlánc): Lista  {TODO ("nincs megvalósítva")}

    Bár a visszatérési érték List , a Semmit nem adjuk meg. Pontosan azért, mert semmi sem öröklődik minden osztályból:

     fun doSomething (): Valami = TODO ()

    A kód nagyon jól összeáll, mert Semmi sem öröklik a Valamitől. De az alkalmazás azonnal összeomlik a NotImplementedError programmal, ha meghívja a doSomething metódust.

    Érdekes módon nem írhat ilyesmit a Java-ra: a kód egyszerűen nem fordul össze, mert a Void nem örökli a String-et:

     statikus Void todo () {dobjon új RuntimeException-t ("Nincs megvalósítva"); } Karakterlánc myMethod () {return todo (); }

    Egy másik példa a végrehajtásra vonatkozhat, például adatkérés adatbázisból vagy távoli szerverről. Ha hiba lép fel, akkor az adatok helyett null értéket adhat vissza. És ez teljesen normális, nincs adat:

     fun getData (): Adatok? = ...

    Mi van, ha egy kicsit több információt szeretne, nem csak nullát? Például megtudhatja a hiba típusát. Itt nem jön semmi a megmentésre:

     fun getData (onError: (SomeError) -> Semmi): Data = ...

    Így nézhet ki a kódban:

     val data = getData () {err -> mikor (err) {értéke InvalidStatement -> dobás Kivétel (err.parseError) NoSuchData -> ...}} return Data () // sikeres szkript}

    Javítsuk ki:

     // Összeállítás általában fun funOne (): Unit {while (true) {}} fun funTwo (): Semmi {while (true) {}} // Ok fun funThree (): Unit {println ("hi")} / / Nem jó szórakozás funFour (): Semmi {println ("szia")}

    Bármi

    Bármely osztály a hierarchia tetején áll – Kotlinban az összes osztály örököl Anyitól. Bármelyik analóg az Java objektummal, de kevesebb módszerrel:

     nyilvános nyílt osztály Bármely {public open operator fun egyenlő (egyéb: Bármi?): Boole-i nyilvános open fun hashCode (): Int nyilvános open fun toString (): String}

    Tizenegy módszer létezik a java.lang.Object fájlban, és öt közülük többszálas kezeléssel foglalkozik. A kisebb számú módszer ellenére Java-kódra történő fordításkor bármelyik osztálynak hiányoznak – itt nyugodt lehet.

    Nulla

    Kotlinban a null semmisséges típusokat alkothat (“nullable” -nek ejtve). Jelzéssel jelzik? a típus végén. Például String? String + null típusú. Vagyis az érték lehet string, vagy lehet null. A Java-ban ilyen kiegészítésekre nincs szükség – minden objektum null lehet, és ez a Kotlin nyelv egyik előnyéhez vezet a Java-val szemben – a null biztonsághoz.

    A Java-ban mindig meghívhatja az objektum metódusait, és csak a program munkája során tudja meg, hogy az objektuma null. Ezután az alkalmazás összeomlik egy NPE (NullPointerException) hibával. Ez általában a Java leggyakoribb hibája.

    Kotlinban a kódod egyszerűen nem fordul össze, ha olyan objektumokat hívsz meg, amelyek nullák lehetnek, vagyis? Signal vannak jelölve. Kötelező null ellenőrzés szükséges. Ha a típus nincs a végén? – garantálja, hogy az objektum soha nem lehet null. Ez segít azonosítani az NPE-vel kapcsolatos esetleges hibákat, még a kódírás szakaszában is – és nem akkor, amikor az alkalmazás már fut, vagy a boltban van, mint a Java esetében.

    A Kotlin létrehozásakor a fejlesztők igyekeztek a lehető legbiztonságosabbá tenni. Írjuk a következő kódot:

     var notNullable: String = "" notNullable = null // Fordítási hiba

    Mit kapunk ennek eredményeként? Összeállítási hiba. A null eltárolásához egy változóban megfelelően deklarálnia kell:

     var nullable: Karakterlánc? = ""

    Ha egy nullázhatatlan változó értékét próbálja hozzárendelni egy nem nullázhatatlan változóhoz, a fordító megakadályozza a következő kód fordítását:

     nontNullable = nullable // Fordítási hiba

    Emellett nem fogunk tudni egy ilyen változóban tárolt objektum metódusait meghívni:

     val hossz = nullable.length // Fordítási hiba

    Ha olyan nullázható változóhoz kíván értéket rendelni, amely nem támogatja a null értéket, először ellenőriznie kell, hogy a nullable tartalmaz-e null értéket:

     if (nullable! = null) {length = nullable.length // OK nonNullable = nullable // OK}

    Ezt követően az ellenőrzés körében a nullable változót a fordító nem nullable típusnak tekinti. Biztonságosan hozzáférhet egy változóban tárolt objektumhoz.

    A NullPointerException elleni védelem fordítói szinten valósul meg. Ez nemcsak a változókra vonatkozik, hanem a kifejezésekre és a függvényhívásokra is. A fordító nem engedi átadni egy nullázható típusokat támogató változó értékét egy függvénynek, ha a funkciódefinícióban csak nonNull paraméterek vannak deklarálva. És ez nem teszi lehetővé olyan változó hozzárendelését, amely nem támogatja a null értéket, azt az értéket, amely egy olyan kifejezésből származik, amely null értéket adhat vissza.

     var name: String = "Ivan" var fullName: Karakterlánc? = "" fun checkStirng (s: String): Karakterlánc? {...} checkString (fullName) // Fordítási hiba neve = checkString (név) // Fordítási hiba

    Lássunk egy másik példát a Java-ból:

     osztály Személy {Preson (String keresztnév, String második név, int kor) {...}} Személy személy = új Személy (null, null, 29); person.getFirstName (). hossz ()

    A kód végrehajtásakor a program hibával összeomlik. És csak az előadás során tudunk meg róla. Természetesen ez a kód egyszerűsített változata, ahol a hiba azonnal látható. De egy valódi programban nehéz megtalálni az ilyen hibákat. Mit kínál Kotlin:

     osztály Személy (keresztnév: Karakterlánc, másodikNév: Karakterlánc, életkor: Int) val személy = Személy (null, null, 29) // fordítási hiba

    Kotlinban, annak semmissé váló típusaival, ez a kód egyszerűen nem fog fordítani. A konstruktorában található Person osztály olyan típusú paraméterekkel rendelkezik, amelyek nem támogatják a null értéket. Ezért a fordító nyomon tudja követni ezt, és nem engedi, hogy ilyen kódot gyűjtsön. Csak akkor, ha kifejezetten és meghatározott célból jelzi, hogy a paraméterek nullák lehetnek, a kód összeáll és az alkalmazás elindul. De akkor az NPE-vel kapcsolatos minden felelősség Önre hárul:

     osztály Személy (keresztnév: Karakterlánc?, másodikNév: Karakterlánc?, kor: Int?) val személy = Személy (null, null, null) // Minden rendben van!

    A Java nyelvi szinten nem támogatja a null biztonságot, ezért ott megjegyzéseket kell használnia. Ez nem csak extra kódsorokat ad hozzá, de nem is garantálja a biztonságot – a kód jól épít, és elfogadja a nullat ott is, ahol nem kellene. A kommentár csak a problémás területeket emeli ki. Kotlinban az ilyen kód egyszerűen nem áll össze.

    Minden alkalommal, amikor nullát írunk be, a „ha (s! = Null) …” nem tűnik vonzónak. Kotlin pedig kényelmesebb eszközöket kínál a nullázhatatlan típusokkal való munkavégzéshez. Beszéljünk róluk.

    Biztonságos híváskezelő

    Az első ilyen eszköz a Secure Call Operator. Úgy néz ki, mint egy kérdőjel, amelyet egy pont követ:

     val név: Húr? = "John" val nameLength: Int? = név? .hossz

    A metódus meghívása előtt ellenőrzi a nullát. Ha a változó értéke null, akkor kivétel helyett ez a kifejezés egyszerűen nullát ad vissza. Vagyis, ha a név == null, akkor a nameLength értéke == null vagy a nameLength == 4 lesz . Nagyon kényelmes és gyors ellenőrzés, amelyet gyakran használnak kódban (alkalmazásunkban ezt az operátort is használni fogjuk).

    “Elvis” kezelő

    Egy másik kényelmes kezelő a biztonságos munkavégzéshez. Elvis betűje:? (Kérdőjel, amelyet kettőspont követ). Ha felhasználja fantáziáját és szögből nézi a felvételt, hasonlóságokat találhat Presley képével:

     val nameLength: Int = név? .hossz ?: 1

    A működés elve a következő: ha a bal oldalon lévő kifejezés nem tér vissza nullára, akkor megkapjuk a név hosszát; ha null, akkor az operátor jobb oldalán lévő kifejezés értéke visszatér. Ez megkönnyíti a null érték ellenőrzését és az alapértelmezett érték visszaadását. A fenti példa alapján, ha a név == null, akkor a nameLength értéke == 1 vagy a nameLength == 4 lesz.

    Egyelőre ennyi, maradjunk kapcsolatban! Ez az első cikk az “Oktatási program” sorozatból. A következő bejegyzések gyűjteményekről, kiterjesztésekről, többszörös öröklésről, lezárt osztályokról és még sok minden másról szólnak – kövesse a blogot!

    OLVASS TOVÁBB:  Új szakma - mobilalkalmazás-tesztelő

    Friss cikkek

    Аутстаффинг в IT: что это и как устроиться работать на аутстаффинг

    Аутстаффинг становится все более распространенной практикой в IT-сфере, «отжимая» популярность и клиентов у аутсорсинга. По мнению экспертов, в ближайшее время эта тенденция сохранится, и...

    NaZapad 16: как попасть в ТОП в бурже, не имея бюджета и опыта

    На практической конференции по продвижению на западных рынках NaZapad 16 Илья Гринько рассказал о том, как создал свой проект в бурже и попробовал его...

    BI-системы: что это и зачем они нужны бизнесу

    Вникаем в основы бизнес-аналитики04 марта 20216 минут66https://d2xzmw6cctk25h.cloudfront.net/post/2564/og_image/0de7185dc6e58fe6f536564315226e43.png Статья подготовлена экспертами факультета BI-аналитики GeekBrains. На международных рынках компании-гиганты работают с миллионами, десятками, а кто-то — и с...

    Kapcsolódó történetek

    HOZZÁSZÓLOK A CIKKHEZ

    Kérjük, írja be véleményét!
    írja be ide nevét

    Maradjon op - Ge a napi híreket a postaládájában

    OLVASS TOVÁBB:  "A" tűzőgép tesztelése "feladat különösen szokatlan volt."