Hoe variabelen en constanten in Go gebruiken

Variabelen zijn een belangrijk programmeerconcept om te beheersen. Ze zijn symbolen die staan voor een waarde die je in een programma gebruikt.

Deze tutorial zal enkele basisprincipes van variabelen en best practices voor het gebruik ervan binnen de Go-programma’s die je maakt, behandelen.

Variabelen Begrijpen

Technisch gezien is een variabele het toewijzen van een opslaglocatie aan een waarde die gekoppeld is aan een symbolische naam of identifier. We gebruiken de variabelenaam om die opgeslagen waarde binnen een computerprogramma te benaderen.

We kunnen ons een variabele voorstellen als een label met een naam erop, dat je vastbindt aan een waarde.

Stel dat we een integer hebben, 1032049348, en we willen die opslaan in een variabele in plaats van continu het lange getal opnieuw te typen. Om dit te bereiken, kunnen we een gemakkelijk te onthouden naam gebruiken, zoals de variabele i. Om een waarde in een variabele op te slaan, gebruiken we de volgende syntaxis:

i := 1032049348

We kunnen deze variabele zien als een label dat vastzit aan de waarde.

Het label heeft de variabelenaam i erop geschreven, en is vastgebonden aan de integerwaarde 1032049348.

De uitdrukking i := 1032049348 is een declaratie- en toekenningsstatement dat uit verschillende onderdelen bestaat:

  • de variabelenaam (i)
  • de korte variabele declaratie toekenning (:=)
  • De waarde die aan de variabelenaam wordt gekoppeld (1032049348)
  • de door Go ingeschatte gegevenstype (int)

We zullen later zien hoe we het type expliciet instellen in het volgende hoofdstuk.

Samen maken deze delen het statement op dat de variabele i gelijk stelt aan de waarde van het integer 1032049348.

Zodra we een variabele gelijk stellen aan een waarde, initialiseren of maken we die variabele. Zodra we dat hebben gedaan, zijn we klaar om de variabele te gebruiken in plaats van de waarde.

Zodra we i gelijk hebben gesteld aan de waarde van 1032049348, kunnen we i gebruiken in plaats van het integer, dus laten we het afdrukken:

package main

import "fmt"

func main() {
	i := 1032049348
	fmt.Println(i)
}
Output
1032049348

We kunnen ook snel en gemakkelijk wiskunde doen door variabelen te gebruiken. Met i := 1032049348, kunnen we de integerwaarde 813 aftrekken met de volgende syntaxis:

fmt.Println(i - 813)
Output
1032048535

In dit voorbeeld doet Go de wiskunde voor ons, door 813 van de variabele i af te trekken om de som 1032048535 terug te geven.

Over wiskunde gesproken, variabelen kunnen gelijk worden gesteld aan het resultaat van een wiskundige vergelijking. Je kunt ook twee getallen optellen en de waarde van de som opslaan in de variabele x:

x := 76 + 145

Je hebt misschien gemerkt dat dit voorbeeld lijkt op algebra. Op dezelfde manier dat we letters en andere symbolen gebruiken om getallen en aantallen voor te stellen binnen formules en vergelijkingen, zijn variabelen symbolische namen die de waarde van een gegevenstype vertegenwoordigen. Voor de juiste Go syntaxis moet je ervoor zorgen dat je variabele aan de linkerkant van elke vergelijking staat.

Laten we nu x afdrukken:

package main

import "fmt"

func main() {
	x := 76 + 145
	fmt.Println(x)
}
Output
221

Go returned the waarde 221 omdat de variabele x werd ingesteld als de som van 76 en 145.

Variabelen kunnen elke datatype zijn, niet alleen integers:

s := "Hello, World!"
f := 45.06
b := 5 > 9 // Een boolean waarde zal altijd true of false teruggeven
array := [4]string{"item_1", "item_2", "item_3", "item_4"}
slice := []string{"one", "two", "three"}
m := map[string]string{"letter": "g", "number": "seven", "symbol": "&"}

Als je een van deze variabelen print, geeft Go wat die variabele equivalent is. Laten we werken met de aanroepstatement voor het typetje slice gegevens:

package main

import "fmt"

func main() {
	slice := []string{"one", "two", "three"}
	fmt.Println(slice)
}
Output
[one two three]

We hebben de waarde van de slicetype []string{"one", "two", "three"} toegevoegd aan de variabele slice, en daarna hebben we de fmt.Println functie gebruikt om die waarde te printen door middel van slice.

Variabelen werken door een kleine ruimte in je computer te reserveren die bepaaldelijke waarden accepteert die dan worden geassocieerd met die ruimte.

Variabelen declareren

In Go zijn er meerdere manieren om een variabele te declareren, en in sommige gevallen zijn er meer dan één manier om dezelfde variabele en waarde te declareren.

We kunnen een variabele i declareren van datatype int zonder initialisatie. Dit betekent dat we een ruimte declareren om een waarde te plaatsen, maar niet hem een initiaal waarde te geven:

var i int

Dit maakt een variabele i van datatype int aan.

Wij kunnen de waarde initialiseren door gebruik te maken van de gelijkheidsteken (=), zoals in het volgende voorbeeld:

var i int = 1

In Go zijn beide vormen van declaratie bekend als lange variabeledeclaraties.

We kunnen ook korte variabeledeclaraties gebruiken:

i := 1

In dit geval hebben we een variabele genaamd i, en een datatype van int. Wanneer we geen datatype specificeren, gebruikt Go de inferred data type.

Met de drie manieren om variabelen te declareren, heeft de Go-community de volgende idiomen adoptie gemaakt:

  • Gebruik alleen de lange formaat, var i int, wanneer je de variabele niet initialiseert.

  • Gebruik de korte formaat, i := 1, wanneer je de variabele declareert en initialiseert.

  • Als je niet wilt dat Go de datatype inferentie doet, maar je wel de korte variabeledeclaratie wil gebruiken, kan je de gewenste type om de waarde wrappen met de volgende syntax:

i := int64(1)

Het is niet gebruikelijk in Go om de lange variabeledeclaratieform te gebruiken wanneer we de waarde initialiseren:

var i int = 1

Het is goed praktisch te volgen hoe de Go-community typische variabeledeclaraties gebruikt, zodat anderen uw programma gemakkelijk kunnen lezen.

Nulwaarden

Alle ingebouwde types hebben een nulwaarde. Elke toegewezen variabele is bruikbaar, zelfs als deze nooit een waarde heeft gekregen. We kunnen de nulwaarden voor de volgende types zien:

package main

import "fmt"

func main() {
	var a int
	var b string
	var c float64
	var d bool

	fmt.Printf("var a %T = %+v\n", a, a)
	fmt.Printf("var b %T = %q\n", b, b)
	fmt.Printf("var c %T = %+v\n", c, c)
	fmt.Printf("var d %T = %+v\n\n", d, d)
}
Output
var a int = 0 var b string = "" var c float64 = 0 var d bool = false

We hebben het %T gebaar gebruikt in de fmt.Printf statement. Dit vertelt de functie om het datatype voor de variabele af te drukken.

In Go, omdat alle waarden een nul waarde hebben, kunnen we geen ongedefinieerde waarden hebben zoals in sommige andere talen. Bijvoorbeeld, een boolean in sommige talen kan ongedefinieerd, waar of onwaar zijn, wat toelaat dat de variabele drie toestanden heeft. In Go kunnen we niet meer dan twee toestanden voor een boolean waarde hebben.

Naamgeving van Variabelen: Regels en Stijl

De naamgeving van variabelen is redelijk flexibel, maar er zijn enkele regels om in gedachten te houden:

  • Variabelenamen mogen slechts één woord zijn (dus geen spaties).
  • Variabelenamen moeten alleen bestaan uit letters, cijfers en underscores (_).
  • Variabelenamen mogen niet beginnen met een cijfer.

Volgens deze regels, laten we eens kijken naar zowel geldige als ongeldige variabelenamen:

Valid Invalid Why Invalid
userName user-name Hyphens are not permitted
name4 4name Cannot begin with a number
user $user Cannot use symbols
userName user name Cannot be more than one word

Vergeet ook niet dat variabelen hoofdlettergevoelig zijn. Deze namen userName, USERNAME, UserName en uSERnAME zijn allemaal volledig verschillende variabelen. Het is een best practice om binnen een programma vergelijkbare variabelenamen te vermijden om ervoor te zorgen dat zowel jij als je medewerkers—huidige en toekomstige—jouw variabelen goed kunnen onderscheiden.

Hoewel variabelen hoofdlettergevoelig zijn, heeft de hoofdletter van de eerste letter van een variabele een speciale betekenis in Go. Als een variabele met een hoofdletter begint, dan is die variabele toegankelijk buiten het pakket waarin het is gedeclareerd (of geëxporteerd). Als een variabele met een kleine letter begint, dan is deze alleen beschikbaar binnen het pakket waarin het is gedeclareerd.

var Email string
var password string

Email begint met een hoofdletter en kan worden benaderd door andere pakketten. password begint met een kleine letter en is alleen toegankelijk binnen het pakket waarin het is gedeclareerd.

Het is gebruikelijk in Go om zeer beknopte (of korte) variabelenamen te gebruiken. Gezien de keuze tussen het gebruik van userName en user voor een variabele, zou het idiomatisch zijn om user te kiezen.

De scope speelt ook een rol in de beknoptheid van de variabelenaam. De regel is dat hoe kleiner het bereik waarin de variabele bestaat, hoe korter de variabelenaam:

names := []string{"Mary", "John", "Bob", "Anna"}
for i, n := range names {
	fmt.Printf("index: %d = %q\n", i, n)
}

We gebruiken de variabele names in een groter bereik, dus het is gebruikelijk om er een betekenisvollere naam aan te geven om te helpen onthouden wat het betekent in het programma. We gebruiken echter de variabelen i en n onmiddellijk in de volgende regel code, en gebruiken ze daarna niet meer… Door dit te doen, zal het niet verwarren voor iemand die de code leest over waar de variabelen worden gebruikt, of wat ze betekenen.

Laten we vervolgens enkele aantekeningen bespreken over variabele stijl. De stijl is om MixedCaps of mixedCaps te gebruiken in plaats van underscores voor namen met meerdere woorden.

Conventional Style Unconventional Style Why Unconventional
userName user_name Underscores are not conventional
i index prefer i over index as it is shorter
serveHTTP serveHttp acronyms should be capitalized

Het belangrijkste aspect van stijl is consistent te zijn, en dat het team waarop je werkt akkoord gaat met de stijl.

Variabelen Opnieuw Toewijzen

Zoals het woord “variabele” suggereert, kunnen we Go-variabelen gemakkelijk wijzigen. Dit betekent dat we een andere waarde kunnen koppelen aan een eerder toegewezen variabele door opnieuw toe te wijzen. Het kunnen opnieuw toewijzen is nuttig omdat we gedurende de loop van een programma mogelijk gebruikersgegenereerde waarden moeten accepteren in al geïnitialiseerde variabelen. We moeten mogelijk de toewijzing ook wijzigen naar iets dat eerder is gedefinieerd.

Wetende dat we een variabele gemakkelijk opnieuw kunnen toewijzen, kan nuttig zijn bij het werken aan een groot programma dat door iemand anders is geschreven, en het is niet duidelijk welke variabelen al zijn gedefinieerd.

Laten we de waarde van 76 toewijzen aan een variabele genaamd i van het type int, en deze vervolgens een nieuwe waarde van 42 geven:

package main

import "fmt"

func main() {
	i := 76
	fmt.Println(i)

	i = 42
	fmt.Println(i)
}
Output
76 42

Dit voorbeeld laat zien dat we eerst de variabele i kunnen toewijzen met de waarde van een integer, en vervolgens de variabele i opnieuw kunnen toewijzen met de waarde 42.

Opmerking: Wanneer je een variabele declareert en initialiseert, kun je := gebruiken, echter, wanneer je alleen de waarde van een reeds gedeclareerde variabele wilt wijzigen, hoef je alleen de gelijk-operator (=) te gebruiken.

Omdat Go een getypeerde taal is, kunnen we niet één type toewijzen aan een ander. Bijvoorbeeld, we kunnen de waarde "Sammy" niet toewijzen aan een variabele van het type int:

i := 72
i = "Sammy"

Het proberen van verschillende types aan elkaar toe te wijzen zal resulteren in een compileerfout:

Output
cannot use "Sammy" (type string) as type int in assignment

Go staat ons niet toe een variabelenaam meer dan één keer te gebruiken:

var s string
var s string
Output
s redeclared in this block

Als we proberen de korte variabelendeclaratie meer dan één keer te gebruiken voor dezelfde variabelenaam, krijgen we ook een compilatiefout. Dit kan per ongeluk gebeuren, dus het begrijpen wat het foutbericht betekent is handig:

i := 5
i := 10
Output
no new variables on left side of :=

Net zoals bij variabelendeclaratie, zal het overwegen van de naamgeving van je variabelen de leesbaarheid van je programma verbeteren voor jou en anderen, wanneer je het in de toekomst bezoekt.

Meerdere Toewijzing

Go stelt ons ook in staat om meerdere waarden toe te wijzen aan meerdere variabelen binnen dezelfde regel. Elke van deze waarden kan van een ander datatype zijn:

j, k, l := "shark", 2.05, 15
fmt.Println(j)
fmt.Println(k)
fmt.Println(l)
Output
shark 2.05 15

In dit voorbeeld werd de variabele j toegewezen aan de string "shark", de variabele k werd toegewezen aan de float 2.05, en de variabele l werd toegewezen aan het gehele getal 15.

Deze aanpak om meerdere variabelen aan meerdere waarden toe te wijzen in één regel kan het aantal regels in je code beperken. Het is echter belangrijk om leesbaarheid niet op te offeren voor minder regels code.

Globale en Lokale Variabelen

Bij het gebruik van variabelen in een programma is het belangrijk om variabele scope in gedachten te houden. De scope van een variabele verwijst naar de specifieke plaatsen waar deze toegankelijk is binnen de code van een bepaald programma. Dit betekent dat niet alle variabelen toegankelijk zijn vanuit alle delen van een bepaald programma—sommige variabelen zullen globaal zijn en sommige lokaal.

Globale variabelen bestaan buiten functies. Lokale variabelen bestaan binnen functies.

Laten we eens kijken naar globale en lokale variabelen in actie:

package main

import "fmt"


var g = "global"

func printLocal() {
	l := "local"
	fmt.Println(l)
}

func main() {
	printLocal()
	fmt.Println(g)
}
Output
local global

Hier gebruiken we `var g = "global"` om een globale variabele buiten de functie te creëren. Vervolgens definiëren we de functie `printLocal()`. Binnen de functie wordt een lokale variabele genaamd `l` toegewezen en vervolgens afgedrukt. Het programma eindigt door `printLocal()` aan te roepen en vervolgens de globale variabele `g` af te drukken.

Omdat `g` een globale variabele is, kunnen we ernaar verwijzen in `printLocal()`. Laten we het vorige programma aanpassen om dat te doen:

package main

import "fmt"


var g = "global"

func printLocal() {
	l := "local"
	fmt.Println(l)
	fmt.Println(g)
}

func main() {
	printLocal()
	fmt.Println(g)
}
Output
local global global

We beginnen met het declareren van een globale variabele `g`, `var g = "global"`. In de `main` functie roepen we de functie `printLocal` aan, die een lokale variabele `l` declareert en deze afdrukt, `fmt.Println(l)`. Vervolgens drukt `printLocal` de globale variabele `g` af, `fmt.Println(g)`. Hoewel `g` niet binnen `printLocal` gedefinieerd was, kon deze nog steeds worden benaderd omdat deze in een globale scope was gedeclareerd. Tot slot drukt de `main` functie ook `g` af.

Laten we nu proberen de lokale variabele buiten de functie aan te roepen:

package main

import "fmt"

var g = "global"

func printLocal() {
	l := "local"
	fmt.Println(l)
}

func main() {
	fmt.Println(l)
}

Output
undefined: l

We kunnen een lokale variabele niet buiten de functie gebruiken waarin deze is toegewezen. Als je dat probeert, krijg je een `undefined` foutmelding bij het compileren.

Laten we naar nog een voorbeeld kijken waarbij we dezelfde variabelenaam gebruiken voor een globale variabele en een lokale variabele:

package main

import "fmt"

var num1 = 5

func printNumbers() {
	num1 := 10
	num2 := 7  

	fmt.Println(num1)
	fmt.Println(num2)
}

func main() {
	printNumbers()
	fmt.Println(num1)
}
Output
10 7 5

In dit programma hebben we de variabele num1 twee keer gedeclareerd. Eerst hebben we num1 op het globale niveau gedeclareerd, var num1 = 5, en vervolgens binnen het lokale bereik van de printNumbers functie, num1 := 10. Wanneer we num1 afdrukken vanuit het main programma, zien we de waarde 5 afgedrukt. Dit komt omdat main alleen de globale variabeledeclaratie ziet. Echter, wanneer we num1 afdrukken vanuit de printNumbers functie, ziet deze de lokale declaratie en drukt deze de waarde 10 af. Hoewel printNumbers een nieuwe variabele genaamd num1 creëert en deze een waarde van 10 toekent, heeft dit geen invloed op het globale exemplaar van num1 met de waarde 5.

Bij het werken met variabelen moet u ook overwegen welke delen van uw programma toegang nodig hebben tot elke variabele; kies daarom passend voor een globale of lokale variabele. In Go-programma’s zult u vinden dat lokale variabelen over het algemeen vaker voorkomen.

Constanten

Constanten zijn vergelijkbaar met variabelen, behalve dat ze niet kunnen worden gewijzigd zodra ze zijn gedeclareerd. Constanten zijn handig voor het definiëren van een waarde die meerdere keren in uw programma zal worden gebruikt, maar die niet mag veranderen.

Bijvoorbeeld, als we de belastingtarief willen declareren voor een winkelwagen systeem, kunnen we een constante gebruiken en dan belasting in verschillende delen van ons programma berekenen. Op een bepaald moment in de toekomst, als de belastingtarief verandert, hoeven we alleen die waarde op één plek in ons programma te veranderen. Als we een variabele gebruikten, is het mogelijk dat we per ongeluk de waarde ergens in ons programma veranderen, wat zou resulteren in een onjuiste berekening.

Om een constante te declareren, kunnen we de volgende syntaxis gebruiken:

const shark = "Sammy"
fmt.Println(shark)
Output
Sammy

Als we proberen een constante te wijzigen nadat deze is gedeclareerd, krijgen we een compile-time fout:

Output
cannot assign to shark

Constanten kunnen untyped zijn. Dit kan handig zijn bij het werken met getallen zoals integer-type data. Als de constante untyped is, wordt deze expliciet geconverteerd, waar typed constanten dat niet doen. Laten we zien hoe we constanten kunnen gebruiken:

package main

import "fmt"

const (
	year     = 365
	leapYear = int32(366)
)

func main() {
	hours := 24
	minutes := int32(60)
	fmt.Println(hours * year)    
	fmt.Println(minutes * year)   
	fmt.Println(minutes * leapYear)
}
Output
8760 21900 21960

Als je een constante met een type declareert, zal het dat exacte type zijn. Hier, wanneer we de constante leapYear declareren, definiëren we het als data type int32. Daarom is het een typed constante, wat betekent dat het alleen kan werken met int32 data types. De year constante die we declareren zonder type, wordt daarom als untyped beschouwd. Vanwege dit, kun je het gebruiken met elk integer data type.

Toen hours werd gedefinieerd, werd afgeleid dat het van het type int was omdat we het niet expliciet een type gaven, hours := 24. Toen we minutes declareerden, declareerden we het expliciet als een int32, minutes := int32(60).

Laten we nu elk berekening doorlopen en waarom het werkt:

hours * year

In dit geval is hours een int, en years is ongetyped. Wanneer het programma compileert, wordt years expliciet geconverteerd naar een int, waardoor de vermenigvuldigingsoperatie kan slagen.

minutes * year

In dit geval is minutes een int32, en year is ongetyped. Wanneer het programma compileert, wordt years expliciet geconverteerd naar een int32, waardoor de vermenigvuldigingsoperatie kan slagen.

minutes * leapYear

In dit geval is minutes een int32, en leapYear is een getypeerde constante van int32. Er is deze keer niets voor de compiler om te doen, aangezien beide variabelen al van hetzelfde type zijn.

Als we proberen twee typen te vermenigvuldigen die getypeerd zijn en niet compatibel, zal het programma niet compileren:

fmt.Println(hours * leapYear)
Output
invalid operation: hours * leapYear (mismatched types int and int32)

In dit geval werd hours afgeleid als een int, en leapYear werd expliciet gedeclareerd als een int32. Omdat Go een getypeerde taal is, zijn een int en een int32 niet compatibel voor wiskundige bewerkingen. Om ze te vermenigvuldigen, zou je een converteren naar een int32 of een int moeten.

Conclusie

In deze tutorial hebben we enkele van de gangbare gebruikssituaties van variabelen binnen Go bekeken. Variabelen zijn een belangrijke bouwsteen van programmeren, als symbolen die staan voor de waarde van een gegevenstype dat we in een programma gebruiken.

Source:
https://www.digitalocean.com/community/tutorials/how-to-use-variables-and-constants-in-go