Why does Dart return NULL if a function reaches the end?

Guide til Darts Null-Aware Operatorer

27/09/2008

Rating: 4.12 (4856 votes)

I moderne programmering er håndtering af 'null'-værdier en af de mest almindelige kilder til uventede fejl og nedbrud. En null-referencefejl opstår, når man forsøger at tilgå en metode eller en egenskab på en variabel, der ikke indeholder en værdi, men i stedet er 'null'. Dart-sproget har taget en proaktiv tilgang til dette problem med introduktionen af null safety, en funktion der fundamentalt ændrer, hvordan vi tænker på og arbejder med variable, der potentielt kan være null. Denne funktion gør din kode mere sikker og forudsigelig ved at tvinge dig til eksplicit at håndtere muligheden for null. Kernen i dette system er en række smarte og effektive null-aware operatorer, som gør det nemt og elegant at skrive null-sikker kode. I denne artikel vil vi dykke ned i disse operatorer og vise, hvordan du kan bruge dem til at skrive renere, mere robust og fejlfri Dart-kode.

What is a nullable type in Dart?
Indholdsfortegnelse

Forståelse af Nullable og Non-Nullable Typer

Før vi kaster os over operatorerne, er det afgørende at forstå den grundlæggende ændring, null safety introducerer: opdelingen af typer i to kategorier. Som udgangspunkt er alle typer i Dart nu non-nullable. Det betyder, at en variabel af typen String altid skal indeholde en strengværdi; den kan aldrig være null. Forsøger du at tildele null til den, vil du få en fejl allerede under kompilering.

Men hvad nu hvis du har brug for at repræsentere fraværet af en værdi? Det er her, nullable typer kommer ind i billedet. Ved at tilføje et spørgsmålstegn (?) til en type, erklærer du, at variablen kan indeholde enten en værdi af den specificerede type eller null. For eksempel kan en variabel af typen String? indeholde en streng eller null.

// Non-nullable (kan ikke være null) String navn = "Anders"; // navn = null; // Dette giver en kompileringsfejl // Nullable (kan være null) String? mellemnavn = "Møller"; mellemnavn = null; // Dette er fuldt ud tilladt

Denne opdeling er fundamentet for null safety. Systemet garanterer, at du ikke ved et uheld kan få en null-referencefejl fra en non-nullable variabel. Udfordringen bliver så at håndtere de nullable typer på en sikker måde, og det er præcis, hvad null-aware operatorerne hjælper os med.

En Komplet Gennemgang af Null-Aware Operatorer

Dart tilbyder et rigt sæt af operatorer designet til at gøre arbejdet med nullable typer så smertefrit som muligt. Lad os gennemgå dem én for én med praktiske eksempler.

What is a non-null assertion in Dart?
!, ?, ?? and late explanation in dart null safety with example. Exclamation Mark (!): The exclamation mark (!) is the “non-null assertion operator” in Dart. It is used to indicate that a variable or expression is non-null, overriding the static type analysis.

If-Null Operatoren (??)

Denne operator er din bedste ven, når du vil angive en standardværdi, hvis en variabel er null. Den tjekker udtrykket til venstre, og hvis det ikke er null, returnerer den dets værdi. Hvis det er null, returnerer den værdien af udtrykket til højre.

Uden operatoren ville du skrive noget i stil med dette:

String? brugernavn; String visningsNavn; if (brugernavn != null) { visningsNavn = brugernavn; } else { visningsNavn = 'Gæst'; } print(visningsNavn); // Output: Gæst

Med ?? operatoren kan det samme opnås på en enkelt linje:

String? brugernavn; String visningsNavn = brugernavn ?? 'Gæst'; print(visningsNavn); // Output: Gæst

Det er både mere læseligt og mere kompakt.

Null-Aware Tildelingsoperator (??=)

Denne operator er en variation af if-null operatoren. Den tildeler kun en værdi til en variabel, hvis variablen aktuelt er null. Det er en smart måde at undgå at overskrive en eksisterende værdi.

Overvej et scenarie, hvor du vil sætte en standardværdi, men kun hvis den ikke allerede er sat:

String? brugernavn; // Hvis brugernavn er null, tildel 'Anonym' brugernavn ??= 'Anonym'; print(brugernavn); // Output: Anonym // Prøv igen. Da brugernavn nu har en værdi, sker der intet brugernavn ??= 'Ny bruger'; print(brugernavn); // Output: Anonym

Dette er en elegant erstatning for if (variabel == null) { variabel = værdi; }.

What is a nullable type in Dart?
Dart employs nullable types to prevent errors when variables are declared as null. These nullable types are denoted by adding a “?” to the type declaration, providing a clearer way to handle null values. This feature helps developers write more robust code by explicitly stating which variables can contain null values.

Null-Aware Adgangsoperator (?.)

Dette er en af de mest anvendte operatorer. Den lader dig sikkert tilgå en egenskab eller kalde en metode på et objekt, der potentielt kan være null. Hvis objektet er null, stopper udtrykket og returnerer null i stedet for at kaste en fejl.

Antag at du har en nullable streng og vil have dens længde:

String? tekst = 'Hej Verden'; int? laengde = tekst?.length; print(laengde); // Output: 10 String? andenTekst = null; int? andenLaengde = andenTekst?.length; print(andenLaengde); // Output: null

En særlig smart egenskab ved denne operator er, at den kortslutter hele kæden af kald. Hvis du har objekt?.metode1()?.metode2() og objekt er null, vil resten af kæden blive ignoreret, og det samlede resultat bliver null.

Null Assertion Operatoren (!)

Nogle gange ved du som udvikler mere end compileren. Der kan være situationer, hvor du er 100% sikker på, at en nullable variabel ikke er null på et bestemt sted i koden, selvom compileren ikke kan bevise det. I disse tilfælde kan du bruge null assertion operatoren, !.

Denne operator konverterer en nullable type til dens non-nullable modpart. Det er en måde at sige: "Stol på mig, compiler, denne værdi er ikke null." Men vær forsigtig! Hvis du tager fejl, og værdien rent faktisk er null, vil din applikation kaste en runtime-fejl. Brug den derfor med omtanke.

What is a null-aware operator in Dart?
?? is one of Dart's null-aware operators; it automatically checks for null for you. As stated in the Dart Language Tour: expr1 ?? expr2 If expr1 is non-null, returns its value; otherwise, evaluates and returns the value of expr2.
List<String>? navne = ['Anna', 'Bent']; // Vi ved, at listen ikke er null her, så vi kan bruge '!' String forsteNavn = navne!.first; print(forsteNavn); // Output: Anna // Hvis vi tager fejl: navne = null; // String andetNavn = navne!.first; // Dette vil kaste en fejl ved kørsel!

Operatoren er nyttig, men en god tommelfingerregel er først at se, om problemet kan løses med en null-tjek eller ?? operatoren, før du tyr til !.

Andre Null-Aware Operatorer

Dart har også et par andre, mere specialiserede null-aware operatorer:

  • Null-Aware Indeksoperator (?[]): Bruges til sikkert at tilgå et element i en liste eller et map, der kan være null. minListe?[0] returnerer null, hvis minListe er null, i stedet for at crashe.
  • Null-Aware Cascade Operator (?..): Giver dig mulighed for at udføre en sekvens af operationer på et objekt, der kan være null. Hvis objektet er null, udføres ingen af operationerne.

Sammenligningstabel over Operatorer

For at give et hurtigt overblik, er her en tabel, der opsummerer de vigtigste null-aware operatorer.

OperatorNavnBeskrivelse
??If-NullReturnerer udtrykket til højre, hvis udtrykket til venstre er null.
??=Null-Aware TildelingTildeler kun en værdi, hvis variablen er null.
?.Null-Aware AdgangTilgår sikkert en egenskab eller metode. Returnerer null, hvis objektet er null.
!Null AssertionKonverterer en nullable type til non-nullable. Kaster en fejl, hvis værdien er null.
?[]Null-Aware IndeksTilgår sikkert et indeks på en liste eller et map.

Håndtering af Forsinket Initialisering med `late`

En almindelig udfordring med non-nullable typer er felter i en klasse, som ikke kan initialiseres med det samme i constructoren, men som du ved vil få en værdi, før de bliver brugt. Et klassisk eksempel er data, der hentes fra et netværk. Førhen var løsningen at gøre feltet nullable, men det er ikke ideelt, da det tvinger dig til at bruge null-tjek overalt.

Her introducerer Dart nøgleordet late. Ved at markere en non-nullable variabel med late, lover du compileren, at du vil initialisere den, før den læses for første gang. Dart indsætter derefter et tjek ved kørsel, som kaster en fejl, hvis du bryder dit løfte. Dette giver dig fleksibiliteten fra forsinket initialisering, mens du bevarer sikkerheden fra en non-nullable type.

How to deal with NULL values in Dart?
To deal with null values, Dart uses flow analysis and type promotion. In addition, it provides you with various null-aware operators: ?? ?. ?.. ?...? The if-null operator (??) The following example uses an if statement to check if a variable is null and assign an error message if it is: String? input; String message; if (input != null) {
class DataService { late String hentetData; Future<void> fetchData() async { // Simulerer et netværkskald await Future.delayed(Duration(seconds: 2)); hentetData = 'Vigtige data fra serveren'; } void visData() { print(hentetData); // Sikkert at bruge 'hentetData' her, efter fetchData() er kaldt } } // Anvendelse: final service = DataService(); await service.fetchData(); service.visData(); // Output: Vigtige data fra serveren

Ofte Stillede Spørgsmål (FAQ)

Hvad er den primære forskel på `?.` og `!`?

Den primære forskel er sikkerhed. `?.` er en sikker operator: hvis objektet er null, returnerer udtrykket pænt `null`. `!` er en usikker operator: den fortæller compileren, at du garanterer, at værdien ikke er null. Hvis du tager fejl, crasher dit program. Brug altid `?.` eller andre sikre metoder, medmindre du er absolut sikker.

Hvornår skal jeg bruge `late` i stedet for en nullable type med `?`?

Brug `late`, når en variabel logisk set aldrig bør være `null`, men dens initialisering er forsinket. Dette signalerer klart din intention om, at fraværet af en værdi er en fejl-tilstand. Brug en nullable type (`?`), når `null` er en gyldig og forventet tilstand for variablen (f.eks. en valgfri brugerprofil-oplysning).

Er det muligt helt at undgå `null` i Dart?

Selvom null safety sigter mod at kontrollere `null`, er det ikke et mål at eliminere det. `null` er et nyttigt koncept til at repræsentere fraværet af en værdi. Målet med null safety er at gøre det eksplicit og sikkert at arbejde med `null`, så det ikke fører til uventede fejl. Ved at bruge non-nullable typer som standard og kun tillade `null` hvor det er meningsfuldt, opnår du meget mere robust kode.

Konklusion

Darts null safety og de tilhørende null-aware operatorer er en kraftfuld tilføjelse til sproget, der markant forbedrer kodens kvalitet og pålidelighed. Ved at omfavne non-nullable typer som standard og bruge værktøjer som `??`, `?.` og `late` kan du bygge applikationer, der er mere modstandsdygtige over for en af de mest berygtede fejltyper i programmering. Det kræver en smule tilvænning, men investeringen i at lære disse koncepter betaler sig hurtigt tilbage i form af færre fejl, mindre debugging og en større tillid til din kode.

Hvis du vil læse andre artikler, der ligner Guide til Darts Null-Aware Operatorer, kan du besøge kategorien Sundhed.

Go up