Kerülje el a Swiftnél elkövetett milliárdos hibát

Először is mi a milliárdos hiba? Sir Charles Antony Richard Hoare 1965-ben találta ki a null referenciát az Algol W nyelv részeként. 2009-ben Hoare „milliárd dolláros hibának” minősíti találmányát.

A semmiféle hivatkozás hasznos konstrukció, a Swift nyelv része, ugyanakkor kifejezett része – amelyet nyelvtípus-rendszer képvisel.

Sok más nyelv ment félúton. Van egy típusuk, amely jelzi, hogy az érték null referencia lehet. Például. a C #

-ban

Személy? opt i onal típusú, ez azt jelenti, hogy vigyáznunk kell a p-vel. Lehet, hogy null referencia. Lehetőséget nyújt számunkra a metódusok meghívására anélkül, hogy null pointer kivételbe ütköznénk:

Abban az esetben, ha a p nulla hivatkozás, a kifejezés nem kerül kiértékelésre, és az eredmény null referencia lesz. De csak elhalasztottuk a problémát. A null pointer kivételt a második sorban kapjuk meg. És ezt úgy értem, hogy a C # csak félúton megy. A s típusú karakterlánc. A C # nem akadályozza meg, hogy nullat rendeljünk nem opcionális típushoz.

Az ObjectiveC a null referenciával egy kicsit más módon foglalkozik. Az ObjectiveC alkalmazásban az összes metódushívás semmilyen biztonságban van:

Ebben az esetben a p nulla, a s nulla, a n pedig 0 (nulla). Nincs kivétel, nincs minden test boldog összeomlása ?!

Nem egészen. A nulla (így hívják a null referenciát az ObjectiveC-ben) saját szemantikai. Az int primitív típus. Az ObjectiveC-ben, amikor a metódusokat nulla -ra hívja meg, a primitív típusok alapértelmezett értékeit adják vissza. Tehát azt mondjuk, hogy egy létező személy neve nulla. Ez szemantikailag helytelen. Most hoztuk létre a „megkérdőjelezhető” alkalmazásállapotot. Most nézze meg ezt a példát:

A logikai érték alapértelmezett értéke hamis. Alkalmazási logikánk téves, és még null mutatós kivételt sem kapunk, hogy erről meséljünk.

Az ilyen hibákat egységtesztek is elkapják, de nem lenne jobb, ha nem teljes paranoia módot választanánk?

A Swift-ben ez nem fordítja le:

Ez szintén nem fordítja le:

És ez

A

eredményeként p , s és n hozzárendelésre kerül a nil , az n típusa Int? Egy nem létező személy nevének nincs hossza, ez nulla .

Mi a helyzet a logikai példával?

Nem hajt végre fontos dolgot . Ha azonban más ágat vezetünk be. Bemutatunk egy másik hibát.

Végrehajtjuk a problémák megoldását , bár nem ez a szándékunk . Ez annak a ténynek köszönhető, hogy a p? .hasProblem eredménye nem a Bool , hanem a Bool? . Kétféle megoldás létezik erre a problémára:

Az első megoldást nem javasolnám, mert csak szennyezi a kódot. A második megoldás a következőképpen néz ki:

A guard let utasítás lehetővé teszi számunkra, hogy ezentúl a Person típusú p vel dolgozzunk. Ha a p nulla hivatkozás, le kell állítanunk az alkalmazás folyamatát.

Itt van egy másik példa a típus kicsomagolására

Először azt mutatja, hogy a kicsomagolás láncolható (ez a guard let funkcióval is lehetséges). De ennek a lehetőségnek a legfőbb oka az volt, hogy itt nem kell leállítanunk az alkalmazás folyamatát. Ebben az esetben a kicsomagolt p csak az if utasítás belső hatókörére érvényes. Guard let esetén kicsomagoljuk az aktuális hatókör értékét.

A Swift 1. óta kezdtem el dolgozni a Swift-szel. Kezdetben írtam néhány kis könyvtárat és egy kis alkalmazást, amelyet néhány napig néhány száz ember használt. A Swift nyelvű if let és guard let koncepció nem volt. Tavaly elkezdtem dolgozni egy alkalmazáson, amelyet sokan használnak nap mint nap. És tudod mit? Megtudtam, hogy a ha engedik és a védekeznek mindenképpen a barátaim. Kerülöm a ? metódushívás főleg és a ! használatát.

Az összeomlási és hibabejelentések úgy tűnik, egyetértenek velem