Tutorial Golang
Ce este Go?
Go (cunoscut ศi sub numele de Golang) este un limbaj de programare open source dezvoltat de Google. Este un limbaj compilat tipizat static. Go acceptฤ programarea concomitentฤ, adicฤ permite rularea mai multor procese simultan. Acest lucru se realizeazฤ folosind canale, goroutine, etc. Go Language are garbage collection care face ea รฎnsฤศi gestionarea memoriei ศi permite execuศia amรขnatฤ a funcศiilor.
Vom รฎnvฤศa toate elementele de bazฤ ale Golang รฎn acest tutorial Learn Go Language.
Cum sฤ descฤrcaศi ศi sฤ instalaศi GO
Pas 1) Acceseazฤ https://golang.org/dl/. Descฤrcaศi binarul pentru sistemul dvs. de operare.
Pas 2) Double faceศi clic pe programul de instalare ศi faceศi clic pe Run.
Pas 3) Faceศi clic pe Urmฤtorul

Pas 4) Selectaศi folderul de instalare ศi faceศi clic pe Urmฤtorul.

Pas 5) Faceศi clic pe Terminare odatฤ ce instalarea este finalizatฤ.

Pas 6) Odatฤ ce instalarea este finalizatฤ, o puteศi verifica deschizรขnd terminalul ศi tastรขnd
go version
Aceasta va afiศa versiunea go instalatฤ

Programul First Go โ Go Hello World!
Creaศi un folder numit studyGo. รn acest tutorial รฎn limba Go, vom crea programele noastre go รฎn interiorul acestui folder. Fiศierele Go sunt create cu extensia .merge. Puteศi rula programe Go folosind sintaxa
go run <filename>
Creaศi un fiศier numit first.go ศi adฤugaศi codul de mai jos รฎn el ศi salvaศi
package main
import ("fmt")
func main() {
fmt.Println("Hello World! This is my first Go program\n")
}

Navigaศi la acest folder din terminalul dvs. Rulaศi programul folosind comanda
du-te fugi mai รฎntรขi.du-te
Puteศi vedea imprimarea de ieศire
Hello World! This is my first Go program

Acum sฤ discutฤm despre programul de mai sus.
pachet principal โ Fiecare program Go Language ar trebui sฤ รฎnceapฤ cu un nume de pachet. Go ne permite sฤ folosim pachete รฎn alte programe go ศi, prin urmare, acceptฤ reutilizarea codului. Execuศia unui program Go รฎncepe cu codul din interiorul pachetului numit main.
import fmt โ importฤ pachetul fmt. Acest pachet implementeazฤ funcศiile I/O.
func main() โ Aceasta este funcศia de la care รฎncepe execuศia programului. Funcศia principalฤ ar trebui sฤ fie รฎntotdeauna plasatฤ รฎn pachetul principal. Sub main(), puteศi scrie codul รฎn { }.
fmt.Println โ Aceasta va imprima textul pe ecran prin funcศia Println a fmt.
Notฤ: รn secศiunile de mai jos ale acestui tutorial Go, cรขnd menศionaศi executarea/executarea codului, รฎnseamnฤ sฤ salvaศi codul รฎntr-un fiศier cu extensia .go ศi sฤ รฎl rulaศi folosind sintaxa
go run <filename>
Tipuri de date
Tipurile (tipurile de date) reprezintฤ tipul valorii stocate รฎntr-o variabilฤ, tipul valorii returnate de o funcศie etc.
Existฤ trei tipuri de bazฤ รฎn Go Language
Tipuri numerice โ Reprezintฤ valori numerice care includ valori รฎntregi, virgulฤ mobilฤ ศi complexe. Diferite tipuri numerice sunt:
int8 โ numere รฎntregi cu semn pe 8 biศi.
int16 โ numere รฎntregi cu semn pe 16 biศi.
int32 โ numere รฎntregi cu semn pe 32 biศi.
int64 โ numere รฎntregi cu semn pe 64 biศi.
uint8 โ numere รฎntregi fฤrฤ semn pe 8 biศi.
uint16 โ numere รฎntregi fฤrฤ semn pe 16 biศi.
uint32 โ numere รฎntregi fฤrฤ semn pe 32 biศi.
uint64 โ numere รฎntregi fฤrฤ semn pe 64 biศi.
float32 โ numere รฎn virgulฤ mobilฤ pe 32 de biศi.
float64 โ numere รฎn virgulฤ mobilฤ pe 64 de biศi.
complex64 โ are float32 pฤrศi reale ศi imaginare.
complex128 โ are float32 pฤrศi reale ศi imaginare.
Tipuri de ศiruri โ Reprezintฤ o secvenศฤ de octeศi (caractere). Puteศi face diverse operaศii pe ศiruri, cum ar fi concatenarea ศirurilor, extragerea subศirurilor etc
Tipuri booleene โ Reprezintฤ 2 valori, fie adevฤrate fie false.
Interfaศa Golang
Interfaศa Golang este o colecศie de semnฤturi de metodฤ utilizatฤ de un tip pentru a implementa comportamentul obiectelor. Scopul principal al interfeศei Golang este de a oferi semnฤturi de metodฤ cu nume, argumente ศi tipuri de returnare. Este la latitudinea unui Type sฤ declare ศi sฤ implementeze metoda. O interfaศฤ รฎn Golang poate fi declaratฤ folosind cuvรขntul cheie โinterfaศฤโ.
Variabile
Variabilele indicฤ o locaศie de memorie care stocheazฤ un fel de valoare. Parametrul tip (รฎn sintaxa de mai jos) reprezintฤ tipul de valoare care poate fi stocatฤ รฎn locaศia de memorie.
Variabila poate fi declaratฤ folosind sintaxa
var <variable_name> <type>
Odatฤ ce declaraศi o variabilฤ de tip, puteศi atribui variabila oricฤrei valori de tipul respectiv.
De asemenea, puteศi da o valoare iniศialฤ unei variabile รฎn timpul declaraศiei รฎn sine folosind
var <variable_name> <type> = <value>
Dacฤ declaraศi variabila cu o valoare iniศialฤ, mergeศi ศi deduceศi tipul variabilei din tipul valorii atribuite. Deci, puteศi omite tipul รฎn timpul declaraศiei folosind sintaxa
var <variable_name> = <value>
De asemenea, puteศi declara mai multe variabile cu sintaxa
var <variable_name1>, <variable_name2> = <value1>, <value2>
Programul de mai jos din acest tutorial Go are cรขteva exemple Golang de declaraศii de variabile
package main
import "fmt"
func main() {
//declaring a integer variable x
var x int
x=3 //assigning x the value 3
fmt.Println("x:", x) //prints 3
//declaring a integer variable y with value 20 in a single statement and prints it
var y int=20
fmt.Println("y:", y)
//declaring a variable z with value 50 and prints it
//Here type int is not explicitly mentioned
var z=50
fmt.Println("z:", z)
//Multiple variables are assigned in single line- i with an integer and j with a string
var i, j = 100,"hello"
fmt.Println("i and j:", i,j)
}
Ieศirea va fi
x: 3 y: 20 z: 50 i and j: 100 hello
Go Language oferฤ, de asemenea, o modalitate uศoarฤ de a declara variabilele cu valoare prin omiterea cuvรขntului cheie var folosind
<variable_name> := <value>
Reศineศi cฤ aศi folosit := รฎn loc de =. Nu puteศi folosi := doar pentru a atribui o valoare unei variabile care este deja declaratฤ. := este folosit pentru a declara ศi a atribui valoare.
Creaศi un fiศier numit assign.go cu urmฤtorul cod
package main
import ("fmt")
func main() {
a := 20
fmt.Println(a)
//gives error since a is already declared
a := 30
fmt.Println(a)
}
Executaศi go run assign.go pentru a vedea rezultatul ca
./assign.go:7:4: no new variables on left side of :=
Variabilele declarate fฤrฤ valoare iniศialฤ vor avea 0 pentru tipurile numerice, false pentru boolean ศi ศir gol pentru ศiruri
constante
Variabilele constante sunt acele variabile a cฤror valoare nu poate fi modificatฤ odatฤ ce au fost atribuite. O constantฤ รฎn limbajul de programare Go este declaratฤ prin utilizarea cuvรขntului cheie โconstโ
Creaศi un fiศier numit constant.go ศi cu urmฤtorul cod
package main
import ("fmt")
func main() {
const b =10
fmt.Println(b)
b = 30
fmt.Println(b)
}
Executaศi go run constant.go pentru a vedea rezultatul ca
.constant.go:7:4: cannot assign to b
Pentru exemple de buclฤ
Buclele sunt folosite pentru a executa un bloc de instrucศiuni รฎn mod repetat pe baza unei condiศii. Majoritatea limbajelor de programare oferฤ 3 tipuri de bucle - for, while, do while. Dar limbajul de programare Go acceptฤ doar bucla for.
Sintaxa unei bucle pentru Golang este
for initialisation_expression; evaluation_expression; iteration_expression{
// one or more statement
}
Expresia_iniศializare este executatฤ mai รฎntรขi (ศi doar o datฤ) รฎn Golang pentru bucla.
Apoi evaluation_expression este evaluatฤ ศi dacฤ este adevฤrat, codul din interiorul blocului este executat.
Id-ul expresiei_iteraศie este executat, iar expresia_evaluฤrii este evaluat din nou. Dacฤ este adevฤrat, blocul de instrucศiuni este executat din nou. Aceasta va continua pรขnฤ cรขnd expresia_evaluare devine falsฤ.
Copiaศi programul de mai jos รฎntr-un fiศier ศi executaศi-l pentru a vedea Golang pentru numere de tipฤrire รฎn buclฤ de la 1 la 5
package main
import "fmt"
func main() {
var i int
for i = 1; i <= 5; i++ {
fmt.Println(i)
}
}
Ieศirea este
1 2 3 4 5
Dacฤ altceva
Dacฤ else este o declaraศie condiศionatฤ. Sinaxa este
if condition{
// statements_1
}else{
// statements_2
}
Aici condiศia este evaluatฤ ศi dacฤ este adevฤratฤ instrucศiunile_1 vor fi executate, altfel vor fi executate instrucศiunile_2.
Puteศi folosi declaraศia if ศi fฤrฤ else. De asemenea, puteศi avea declaraศii if else รฎnlฤnศuite. Programele de mai jos vor explica mai multe despre dacฤ altfel.
Executaศi programul de mai jos. Verificฤ dacฤ un numฤr, x, este mai mic de 10. Dacฤ da, va afiศa โx este mai mic de 10โ
package main
import "fmt"
func main() {
var x = 50
if x < 10 {
//Executes if x < 10
fmt.Println("x is less than 10")
}
}
Aici, deoarece valoarea lui x este mai mare decรขt 10, instrucศiunea din interiorul dacฤ condiศia blocului nu va fi executatฤ.
Acum vedeศi programul de mai jos. รn acest tutorial despre limbajul de programare Go, avem un bloc else care va fi executat la eศecul evaluฤrii if.
package main
import "fmt"
func main() {
var x = 50
if x < 10 {
//Executes if x is less than 10
fmt.Println("x is less than 10")
} else {
//Executes if x >= 10
fmt.Println("x is greater than or equals 10")
}
}
Acest program vฤ va oferi rezultate
x is greater than or equals 10
Acum, รฎn acest tutorial Go, vom vedea un program cu mai multe blocuri if else (รฎnlฤnศuite dacฤ else). Executaศi exemplul Go de mai jos. Verificฤ dacฤ un numฤr este mai mic de 10 sau este รฎntre 10-90 sau mai mare de 90.
package main
import "fmt"
func main() {
var x = 100
if x < 10 {
//Executes if x is less than 10
fmt.Println("x is less than 10")
} else if x >= 10 && x <= 90 {
//Executes if x >= 10 and x<=90
fmt.Println("x is between 10 and 90")
} else {
//Executes if both above cases fail i.e x>90
fmt.Println("x is greater than 90")
}
}
Aici, mai รฎntรขi, condiศia if verificฤ dacฤ x este mai mic de 10 ศi nu este. Deci verificฤ urmฤtoarea condiศie (altfel dacฤ) dacฤ este รฎntre 10 ศi 90, ceea ce este, de asemenea, fals. Deci apoi executฤ blocul din secศiunea else care dฤ rezultatul
x is greater than 90
Intrerupator
Switch este o altฤ declaraศie condiศionatฤ. Instrucศiunile Switch evalueazฤ o expresie ศi rezultatul este comparat cu un set de valori disponibile (cazuri). Odatฤ ce o potrivire este gฤsitฤ, instrucศiunile asociate cu acea potrivire (caz) sunt executate. Dacฤ nu se gฤseศte nicio potrivire, nimic nu va fi executat. De asemenea, puteศi adฤuga un caz implicit pentru comutare, care va fi executat dacฤ nu sunt gฤsite alte potriviri. Sintaxa comutatorului este
switch expression {
case value_1:
statements_1
case value_2:
statements_2
case value_n:
statements_n
default:
statements_default
}
Aici valoarea expresiei este comparatฤ cu valorile din fiecare caz. Odatฤ ce este gฤsitฤ o potrivire, instrucศiunile asociate cu acel caz sunt executate. Dacฤ nu se gฤseศte nicio potrivire, instrucศiunile din secศiunea implicitฤ sunt executate.
Executaศi programul de mai jos
package main
import "fmt"
func main() {
a,b := 2,1
switch a+b {
case 1:
fmt.Println("Sum is 1")
case 2:
fmt.Println("Sum is 2")
case 3:
fmt.Println("Sum is 3")
default:
fmt.Println("Printing default")
}
}
Veศi obศine rezultatul ca
Sum is 3
Schimbaศi valoarea lui a ศi b la 3 ศi rezultatul va fi
Printing default
De asemenea, puteศi avea mai multe valori รฎntr-un caz, separรขndu-le cu virgulฤ.
Arrays
Array reprezintฤ o dimensiune fixฤ, numitฤ secvenศฤ de elemente de acelaศi tip. Nu puteศi avea o matrice care conศine atรขt numere รฎntregi, cรขt ศi caractere. Nu puteศi modifica dimensiunea unei matrice odatฤ ce aศi definit dimensiunea.
Sintaxa pentru declararea unui tablou este
var arrayname [size] type
Fiecฤrui element de matrice i se poate atribui o valoare folosind sintaxa
arrayname [index] = value
Indexul matricei รฎncepe de la 0 la mฤrimea-1.
Puteศi atribui valori elementelor de matrice รฎn timpul declaraศiei folosind sintaxa
arrayname := [size] type {value_0,value_1,โฆ,value_size-1}
De asemenea, puteศi ignora parametrul dimensiune รฎn timp ce declaraศi matricea cu valori, รฎnlocuind dimensiunea cu ... iar compilatorul va gฤsi lungimea din numฤrul de valori. Sintaxa este
arrayname := [โฆ] type {value_0,value_1,โฆ,value_size-1}
Puteศi gฤsi lungimea matricei folosind sintaxa
len(arrayname)
Executaศi exemplul Go de mai jos pentru a รฎnศelege matricea
package main
import "fmt"
func main() {
var numbers [3] string //Declaring a string array of size 3 and adding elements
numbers[0] = "One"
numbers[1] = "Two"
numbers[2] = "Three"
fmt.Println(numbers[1]) //prints Two
fmt.Println(len(numbers)) //prints 3
fmt.Println(numbers) // prints [One Two Three]
directions := [...] int {1,2,3,4,5} // creating an integer array and the size of the array is defined by the number of elements
fmt.Println(directions) //prints [1 2 3 4 5]
fmt.Println(len(directions)) //prints 5
//Executing the below commented statement prints invalid array index 5 (out of bounds for 5-element array)
//fmt.Println(directions[5])
}
producศie
Two 3 [One Two Three] [1 2 3 4 5] 5
Golang Slice ศi funcศie de adฤugare
O felie este o porศiune sau un segment dintr-o matrice. Sau este o vedere sau o vedere parศialฤ a unui tablou subiacent cฤtre care indicฤ. Puteศi accesa elementele unei secศiuni folosind numele ศi numฤrul de index la fel ca รฎntr-o matrice. Nu puteศi modifica lungimea unei matrice, dar puteศi modifica dimensiunea unei felii.
Conศinutul unei felii sunt de fapt pointerii cฤtre elementele unui tablou. Inseamna dacฤ modificaศi orice element dintr-o felie, conศinutul matricei de bazฤ va fi de asemenea afectat.
Sintaxa pentru crearea unei felii este
var slice_name [] type = array_name[start:end]
Aceasta va crea o porศiune numitฤ slice_name dintr-o matrice numitฤ array_name cu elementele de la index de la รฎnceput la sfรขrศit-1.
Acum, รฎn acest tutorial Golang, vom executa programul de mai jos. Programul va crea o porศiune din matrice ศi o va imprima. De asemenea, puteศi vedea cฤ modificarea conศinutului din felie va modifica matricea realฤ.
package main
import "fmt"
func main() {
// declaring array
a := [5] string {"one", "two", "three", "four", "five"}
fmt.Println("Array after creation:",a)
var b [] string = a[1:4] //created a slice named b
fmt.Println("Slice after creation:",b)
b[0]="changed" // changed the slice data
fmt.Println("Slice after modifying:",b)
fmt.Println("Array after slice modification:",a)
}
Acesta va imprima rezultatul ca
Array after creation: [one two three four five] Slice after creation: [two three four] Slice after modifying: [changed three four] Array after slice modification: [one changed three four five]
Existฤ anumite funcศii precum Golang len, Golang append pe care le puteศi aplica pe felii
len(nume_slice) โ returneazฤ lungimea feliei
append(nume_slice, valoare_1, valoare_2) โ Golang append este folosit pentru a adฤuga value_1 ศi value_2 la o porศiune existentฤ.
append(slice_nale1,slice_name2...) โ adaugฤ slice_name2 la slice_name1
Executaศi urmฤtorul program.
package main
import "fmt"
func main() {
a := [5] string {"1","2","3","4","5"}
slice_a := a[1:3]
b := [5] string {"one","two","three","four","five"}
slice_b := b[1:3]
fmt.Println("Slice_a:", slice_a)
fmt.Println("Slice_b:", slice_b)
fmt.Println("Length of slice_a:", len(slice_a))
fmt.Println("Length of slice_b:", len(slice_b))
slice_a = append(slice_a,slice_b...) // appending slice
fmt.Println("New Slice_a after appending slice_b :", slice_a)
slice_a = append(slice_a,"text1") // appending value
fmt.Println("New Slice_a after appending text1 :", slice_a)
}
Ieศirea va fi
Slice_a: [2 3] Slice_b: [two three] Length of slice_a: 2 Length of slice_b: 2 New Slice_a after appending slice_b : [2 3 two three] New Slice_a after appending text1 : [2 3 two three text1]
Programul creeazฤ mai รฎntรขi 2 felii ศi i-a imprimat lungimea. Apoi a ataศat o felie la alta ศi apoi a ataศat un ศir la felia rezultatฤ.
funcลฃii
O funcศie reprezintฤ un bloc de instrucศiuni care รฎndeplineศte o anumitฤ sarcinฤ. O declaraศie de funcศie ne spune numele funcศiei, tipul de returnare ศi parametrii de intrare. Definiศia funcศiei reprezintฤ codul conศinut รฎn funcศie. Sintaxa pentru declararea funcศiei este
func function_name(parameter_1 type, parameter_n type) return_type {
//statements
}
Parametrii ศi tipurile de returnare sunt opศionale. De asemenea, puteศi returna mai multe valori dintr-o funcศie.
Acum, รฎn acest tutorial Golang, sฤ rulฤm urmฤtorul exemplu Golang. Aici funcศia numitฤ calc va accepta 2 numere ศi efectueazฤ adunarea ศi scฤderea ศi returneazฤ ambele valori.
package main
import "fmt"
//calc is the function name which accepts two integers num1 and num2
//(int, int) says that the function returns two values, both of integer type.
func calc(num1 int, num2 int)(int, int) {
sum := num1 + num2
diff := num1 - num2
return sum, diff
}
func main() {
x,y := 15,10
//calls the function calc with x and y an d gets sum, diff as output
sum, diff := calc(x,y)
fmt.Println("Sum",sum)
fmt.Println("Diff",diff)
}
Ieศirea va fi
Sum 25 Diff 5
Pachete
Pachetele sunt folosite pentru a organiza codul. รntr-un proiect mare, nu este fezabil sฤ scrieศi cod รฎntr-un singur fiศier. Limbajul de programare Go ne permite sฤ organizฤm codul รฎn diferite pachete. Acest lucru creศte lizibilitatea ศi reutilizarea codului. Un program Go executabil ar trebui sฤ conศinฤ un pachet numit main ศi execuศia programului รฎncepe de la funcศia numitฤ main. Puteศi importa alte pachete รฎn programul nostru folosind sintaxa
import package_name
Vom vedea ศi discuta รฎn acest tutorial Golang, cum sฤ creaศi ศi sฤ utilizaศi pachete รฎn urmฤtorul exemplu Golang.
Pas 1) Creaศi un fiศier numit package_example.go ศi adฤugaศi codul de mai jos
package main
import "fmt"
//the package to be created
import "calculation"
func main() {
x,y := 15,10
//the package will have function Do_add()
sum := calculation.Do_add(x,y)
fmt.Println("Sum",sum)
}
รn programul de mai sus, fmt este un pachet pe care limbajul de programare Go ni-l oferฤ รฎn principal pentru scopuri I/O. De asemenea, puteศi vedea un pachet numit calcul. รn interiorul main() puteศi vedea o sumฤ pasฤ := calcul.Do_add(x,y). รnseamnฤ cฤ invocaศi funcศia Do_add din calculul pachetului.
Pas 2) รn primul rรขnd, ar trebui sฤ creaศi calculul pachetului รฎntr-un folder cu acelaศi nume sub folderul src din go. Calea instalatฤ a go poate fi gฤsitฤ din variabila PATH.
Pentru Mac, gฤsiศi calea executรขnd echo $PATH

Deci calea este /usr/local/go
Pentru Windows, gฤsiศi calea executรขnd echo %GOROOT%

Aici calea este C:\Go\
Pas 3) Navigaศi la folderul src (/usr/local/go/src pentru Mac ศi C:\Go\src pentru Windows). Acum, din cod, numele pachetului este de calcul. Go necesitฤ ca pachetul sฤ fie plasat รฎntr-un director cu acelaศi nume sub directorul src. Creaศi un director numit calcul รฎn folderul src.
Pas 4) Creaศi un fiศier numit calc.go (puteศi da orice nume, dar numele pachetului din cod conteazฤ. Aici ar trebui sฤ fie calcul) รฎn directorul de calcul ศi adฤugaศi codul de mai jos
package calculation
func Do_add(num1 int, num2 int)(int) {
sum := num1 + num2
return sum
}
Pas 5) Rulaศi comanda go install din directorul de calcul care va compila calc.go.

Pas 6) Acum reveniศi la package_example.go ศi rulaศi go run package_example.go. Ieศirea va fi Suma 25.
Reศineศi cฤ numele funcศiei Do_add รฎncepe cu o literฤ majusculฤ. Acest lucru se datoreazฤ faptului cฤ รฎn Go, dacฤ numele funcศiei รฎncepe cu o literฤ majusculฤ, รฎnseamnฤ cฤ alte programe รฎl pot vedea (accesa), altfel alte programe nu รฎl pot accesa. Dacฤ numele funcศiei a fost do_add , atunci aศi fi primit eroarea
nu se poate face referire la calculul numelui neexportat.calc..
Amรขnare ศi stivuire amรขnฤ
Instrucศiunile Defer sunt folosite pentru a amรขna execuศia unui apel de funcศie pรขnฤ cรขnd funcศia care conศine instrucศiunea defer finalizeazฤ execuศia.
Sฤ รฎnvฤศฤm asta cu un exemplu:
package main
import "fmt"
func sample() {
fmt.Println("Inside the sample()")
}
func main() {
//sample() will be invoked only after executing the statements of main()
defer sample()
fmt.Println("Inside the main()")
}
Ieศirea va fi
Inside the main() Inside the sample()
Aici execuศia sample() este amรขnatฤ pรขnฤ cรขnd se finalizeazฤ execuศia funcศiei incluse(main()).
Stacking defer foloseศte mai multe instrucศiuni defer. Sฤ presupunem cฤ aveศi mai multe instrucศiuni defer รฎn interiorul unei funcศii. Go plaseazฤ toate apelurile de funcศii amรขnate รฎntr-o stivฤ ศi, odatฤ ce funcศia de รฎncadrare revine, funcศiile stivuite sunt executate รฎn Comanda Last In First Out (LIFO). Puteศi vedea acest lucru รฎn exemplul de mai jos.
Executaศi codul de mai jos
package main
import "fmt"
func display(a int) {
fmt.Println(a)
}
func main() {
defer display(1)
defer display(2)
defer display(3)
fmt.Println(4)
}
Ieศirea va fi
4 3 2 1
Aici codul din main() se executฤ mai รฎntรขi, iar apoi apelurile de funcศii amรขnate sunt executate รฎn ordine inversฤ, adicฤ 4, 3,2,1.
Pointeri
รnainte de a explica indicatorii, sฤ discutฤm mai รฎntรขi despre operatorul โ&โ. Operatorul โ&โ este folosit pentru a obศine adresa unei variabile. รnseamnฤ cฤ โ&aโ va tipฤri adresa de memorie a variabilei a.
รn acest tutorial Golang, vom executa programul de mai jos pentru a afiศa valoarea unei variabile ศi adresa acelei variabile
package main
import "fmt"
func main() {
a := 20
fmt.Println("Address:",&a)
fmt.Println("Value:",a)
}
Rezultatul va fi
Address: 0xc000078008 Value: 20
O variabilฤ pointer stocheazฤ adresa de memorie a altei variabile. Puteศi defini un pointer folosind sintaxa
var variable_name *type
Asteriscul(*) reprezintฤ variabila este un pointer. Veศi รฎnศelege mai multe executรขnd programul de mai jos
package main
import "fmt"
func main() {
//Create an integer variable a with value 20
a := 20
//Create a pointer variable b and assigned the address of a
var b *int = &a
//print address of a(&a) and value of a
fmt.Println("Address of a:",&a)
fmt.Println("Value of a:",a)
//print b which contains the memory address of a i.e. &a
fmt.Println("Address of pointer b:",b)
//*b prints the value in memory address which b contains i.e. the value of a
fmt.Println("Value of pointer b",*b)
//increment the value of variable a using the variable b
*b = *b+1
//prints the new value using a and *b
fmt.Println("Value of pointer b",*b)
fmt.Println("Value of a:",a)}
Ieศirea va fi
Address of a: 0x416020 Value of a: 20 Address of pointer b: 0x416020 Value of pointer b 20 Value of pointer b 21 Value of a: 21
Structuri
O structurฤ este un tip de date definit de utilizator, care conศine รฎncฤ un element de acelaศi tip sau diferit.
Utilizarea unei structuri este un proces รฎn 2 etape.
Mai รฎntรขi, creaศi (declaraศi) un tip de structurฤ
รn al doilea rรขnd, creaศi variabile de acest tip pentru a stoca valori.
Structurile sunt utilizate รฎn principal atunci cรขnd doriศi sฤ stocaศi รฎmpreunฤ date asociate.
Luaศi รฎn considerare o informaศie despre angajaศi care are numele, vรขrsta ศi adresa. Puteศi gestiona asta รฎn 2 moduri
Creaศi 3 matrice - o matrice stocheazฤ numele angajaศilor, una stocheazฤ vรขrsta ศi al treilea stocheazฤ vรขrsta.
Declaraศi un tip de structurฤ cu 3 cรขmpuri - nume, adresฤ ศi vรขrstฤ. Creaศi o matrice de acel tip de structurฤ รฎn care fiecare element este un obiect de structurฤ avรขnd nume, adresฤ ศi vรขrstฤ.
Prima abordare nu este eficientฤ. รn astfel de scenarii, structurile sunt mai convenabile.
Sintaxa pentru declararea unei structuri este
type structname struct {
variable_1 variable_1_type
variable_2 variable_2_type
variable_n variable_n_type
}
Un exemplu de declaraศie de structurฤ este
type emp struct {
name string
address string
age int
}
Aici este creat un nou tip definit de utilizator numit emp. Acum, puteศi crea variabile de tip emp folosind sintaxa
var variable_name struct_name
Un exemplu este
var empdata1 emp
Puteศi seta valori pentru empdata1 ca
empdata1.name = "John" empdata1.address = "Street-1, Bangalore" empdata1.age = 30
De asemenea, puteศi crea o variabilฤ de structurฤ ศi aloca valori prin
empdata2 := emp{"Raj", "Building-1, Delhi", 25}
Aici, trebuie sฤ menศineศi ordinea elementelor. Raj va fi mapat dupฤ nume, urmฤtorul element de adresat ศi ultimul pentru vรขrsta.
Executaศi codul de mai jos
package main
import "fmt"
//declared the structure named emp
type emp struct {
name string
address string
age int
}
//function which accepts variable of emp type and prints name property
func display(e emp) {
fmt.Println(e.name)
}
func main() {
// declares a variable, empdata1, of the type emp
var empdata1 emp
//assign values to members of empdata1
empdata1.name = "John"
empdata1.address = "Street-1, London"
empdata1.age = 30
//declares and assign values to variable empdata2 of type emp
empdata2 := emp{"Raj", "Building-1, Paris", 25}
//prints the member name of empdata1 and empdata2 using display function
display(empdata1)
display(empdata2)
}
producศie
John Raj
Metode (nu funcศii)
O metodฤ este o funcศie cu un argument receptor. Archidin punct de vedere tehnic, este รฎntre cuvรขntul cheie func ศi numele metodei. Sintaxa unei metode este
func (variable variabletype) methodName(parameter1 paramether1type) {
}
Sฤ convertim exemplul de program de mai sus pentru a folosi metode รฎn loc de funcศie.
package main
import "fmt"
//declared the structure named emp
type emp struct {
name string
address string
age int
}
//Declaring a function with receiver of the type emp
func(e emp) display() {
fmt.Println(e.name)
}
func main() {
//declaring a variable of type emp
var empdata1 emp
//Assign values to members
empdata1.name = "John"
empdata1.address = "Street-1, Lodon"
empdata1.age = 30
//declaring a variable of type emp and assign values to members
empdata2 := emp {
"Raj", "Building-1, Paris", 25}
//Invoking the method using the receiver of the type emp
// syntax is variable.methodname()
empdata1.display()
empdata2.display()
}
Go nu este un limbaj orientat pe obiecte ศi nu are conceptul de clasฤ. Metodele oferฤ o imagine a ceea ce faci รฎn programele orientate pe obiecte รฎn care funcศiile unei clase sunt invocate folosind sintaxa nume obiect.numefuncศie()
Concurenta
Go acceptฤ executarea concomitentฤ a sarcinilor. รnseamnฤ cฤ Go poate executa mai multe sarcini simultan. Este diferit de conceptul de paralelism. รn paralelism, o sarcinฤ este รฎmpฤrศitฤ รฎn subsarcini mici ศi sunt executate รฎn paralel. Dar รฎn concurenศฤ, mai multe sarcini sunt executate simultan. Concurenศa se realizeazฤ รฎn Go folosind Goroutines ศi Canale.
Goroutine
O goroutine este o funcศie care poate rula concomitent cu alte funcศii. De obicei, atunci cรขnd o funcศie este invocatฤ, controlul este transferat รฎn funcศia apelatฤ ศi, odatฤ finalizatฤ, controlul de execuศie revine la funcศia de apelare. Funcศia de apelare รฎศi continuฤ apoi execuศia. Funcศia apelantฤ aศteaptฤ ca funcศia invocatฤ sฤ finalizeze execuศia รฎnainte de a continua cu restul instrucศiunilor.
Dar รฎn cazul goroutine, funcศia de apelare nu va aศtepta finalizarea execuศiei funcศiei invocate. Va continua sฤ se execute cu urmฤtoarele instrucศiuni. Puteศi avea mai multe goroutine รฎntr-un program.
De asemenea, programul principal se va รฎnchide odatฤ ce รฎศi รฎncheie executarea instrucศiunilor ศi nu va aศtepta finalizarea goroutinelor invocate.
Goroutine este invocatฤ folosind cuvรขntul cheie go urmat de un apel de funcศie.
Exemplu
go add(x,y)
Veศi รฎnศelege goroutine cu exemplele Golang de mai jos. Executaศi programul de mai jos
package main
import "fmt"
func display() {
for i:=0; i<5; i++ {
fmt.Println("In display")
}
}
func main() {
//invoking the goroutine display()
go display()
//The main() continues without waiting for display()
for i:=0; i<5; i++ {
fmt.Println("In main")
}
}
Ieศirea va fi
In main In main In main In main In main
Aici programul principal ศi-a รฎncheiat execuศia chiar รฎnainte de a รฎncepe goroutine. Display() este o rutinฤ care este invocatฤ folosind sintaxa
go function_name(parameter list)
รn codul de mai sus, main() nu aศteaptฤ ca display() sฤ se finalizeze, iar main() ศi-a รฎncheiat execuศia รฎnainte ca display() sฤ-ศi execute codul. Deci declaraศia print din display() nu a fost tipฤritฤ.
Acum modificฤm programul pentru a imprima instrucศiunile ศi din display(). Adฤugฤm o รฎntรขrziere de 2 secunde รฎn bucla for a main() ศi o รฎntรขrziere de 1 secundฤ รฎn bucla for a afiศajului().
package main
import "fmt"
import "time"
func display() {
for i:=0; i<5; i++ {
time.Sleep(1 * time.Second)
fmt.Println("In display")
}
}
func main() {
//invoking the goroutine display()
go display()
for i:=0; i<5; i++ {
time.Sleep(2 * time.Second)
fmt.Println("In main")
}
}
Ieศirea va fi oarecum similarฤ cu
In display In main In display In display In main In display In display In main In main In main
Aici puteศi vedea cฤ ambele bucle sunt executate รฎntr-un mod suprapus din cauza execuศiei concurente.
Canale
Canalele sunt o modalitate prin care funcศiile pot comunica รฎntre ele. Poate fi considerat ca un mediu รฎn care o rutinฤ plaseazฤ date ศi este accesatฤ de o altฤ rutinฤ pe serverul Golang.
Un canal poate fi declarat cu sintaxa
channel_variable := make(chan datatype)
Exemplu:
ch := make(chan int)
Puteศi trimite date cฤtre un canal folosind sintaxa
channel_variable <- variable_name
Exemplu
ch <- x
Puteศi primi date de la un canal folosind sintaxa
variable_name := <- channel_variable
Exemplu
y := <- ch
รn exemplele de limbฤ Go de mai sus de goroutine, aศi vฤzut cฤ programul principal nu aศteaptฤ goroutine. Dar nu este cazul cรขnd sunt implicate canale. Sฤ presupunem cฤ dacฤ o rutinฤ รฎmpinge date cฤtre canal, main() va aศtepta instrucศiunea care primeศte datele canalului pรขnฤ cรขnd primeศte datele.
Veศi vedea acest lucru รฎn exemplele de limbฤ Go de mai jos. Mai รฎntรขi, scrieศi o rutinฤ normalฤ ศi vedeศi comportamentul. Apoi modificaศi programul pentru a utiliza canale ศi a vedea comportamentul.
Executaศi programul de mai jos
package main
import "fmt"
import "time"
func display() {
time.Sleep(5 * time.Second)
fmt.Println("Inside display()")
}
func main() {
go display()
fmt.Println("Inside main()")
}
Ieศirea va fi
Inside main()
Main() a terminat execuศia ศi a ieศit รฎnainte ca goroutine sฤ se execute. Deci tipฤrirea din interiorul display() nu a fost executatฤ.
Acum modificaศi programul de mai sus pentru a utiliza canalele ศi a vedea comportamentul.
package main
import "fmt"
import "time"
func display(ch chan int) {
time.Sleep(5 * time.Second)
fmt.Println("Inside display()")
ch <- 1234
}
func main() {
ch := make(chan int)
go display(ch)
x := <-ch
fmt.Println("Inside main()")
fmt.Println("Printing x in main() after taking from channel:",x)
}
Ieศirea va fi
Inside display() Inside main() Printing x in main() after taking from channel: 1234
Aici ceea ce se รฎntรขmplฤ este main() la atingerea x := <-ch va aศtepta date pe canalul ch. Display-ul () are o aศteptare de 5 secunde ศi apoi รฎmpinge datele cฤtre canalul de canal. Main() la primirea datelor de la canal este deblocat ศi รฎศi continuฤ execuศia.
Expeditorul care transmite date pe canal poate informa receptorii cฤ nu vor mai fi adฤugate date la canal prin รฎnchiderea canalului. Acesta este folosit รฎn principal atunci cรขnd utilizaศi o buclฤ pentru a รฎmpinge date cฤtre un canal. Un canal poate fi รฎnchis folosind
close(channel_name)
ศi la capฤtul receptorului, este posibil sฤ verificaศi dacฤ canalul este รฎnchis folosind o variabilฤ suplimentarฤ รฎn timp ce preluaศi date de pe canal folosind
variable_name, status := <- channel_variable
Dacฤ starea este True รฎnseamnฤ cฤ aศi primit date de la canal. Dacฤ este fals, รฎnseamnฤ cฤ รฎncercaศi sฤ citiศi de pe un canal รฎnchis
De asemenea, puteศi utiliza canale pentru comunicarea รฎntre goroutine. Trebuie sฤ utilizaศi 2 goroutine - unul รฎmpinge datele cฤtre canal, iar celฤlalt primeศte datele de la canal. Vezi programul de mai jos
package main
import "fmt"
import "time"
//This subroutine pushes numbers 0 to 9 to the channel and closes the channel
func add_to_channel(ch chan int) {
fmt.Println("Send data")
for i:=0; i<10; i++ {
ch <- i //pushing data to channel
}
close(ch) //closing the channel
}
//This subroutine fetches data from the channel and prints it.
func fetch_from_channel(ch chan int) {
fmt.Println("Read data")
for {
//fetch data from channel
x, flag := <- ch
//flag is true if data is received from the channel
//flag is false when the channel is closed
if flag == true {
fmt.Println(x)
}else{
fmt.Println("Empty channel")
break
}
}
}
func main() {
//creating a channel variable to transport integer values
ch := make(chan int)
//invoking the subroutines to add and fetch from the channel
//These routines execute simultaneously
go add_to_channel(ch)
go fetch_from_channel(ch)
//delay is to prevent the exiting of main() before goroutines finish
time.Sleep(5 * time.Second)
fmt.Println("Inside main()")
}
Aici existฤ 2 subrutine, una รฎmpinge datele cฤtre canal ศi cealaltฤ imprimฤ datele cฤtre canal. Funcศia add_to_channel adaugฤ numerele de la 0 la 9 ศi รฎnchide canalul. Simultan, funcศia fetch_from_channel aศteaptฤ la
x, flag := <- ch ศi odatฤ ce datele devin disponibile, se tipฤreศte datele. Iese odatฤ ce steagul este fals, ceea ce รฎnseamnฤ cฤ canalul este รฎnchis.
Aศteptarea รฎn main() este datฤ pentru a preveni ieศirea din main() pรขnฤ cรขnd goroutines terminฤ execuศia.
Executaศi codul ศi vedeศi rezultatul ca
Read data Send data 0 1 2 3 4 5 6 7 8 9 Empty channel Inside main()
Selectaศi
Select poate fi vฤzut ca o declaraศie de comutare care funcศioneazฤ pe canale. Aici declaraศiile de caz vor fi o operaศiune de canal. De obicei, fiecare declaraศie de caz va fi cititฤ รฎncercare de pe canal. Cรขnd oricare dintre cazuri este gata (canalul este citit), atunci instrucศiunea asociatฤ cu acel caz este executatฤ. Dacฤ sunt pregฤtite mai multe cazuri, va alege unul aleatoriu. Puteศi avea un caz implicit care este executat dacฤ niciunul dintre cazuri nu este pregฤtit.
Sฤ vedem codul de mai jos
package main
import "fmt"
import "time"
//push data to channel with a 4 second delay
func data1(ch chan string) {
time.Sleep(4 * time.Second)
ch <- "from data1()"
}
//push data to channel with a 2 second delay
func data2(ch chan string) {
time.Sleep(2 * time.Second)
ch <- "from data2()"
}
func main() {
//creating channel variables for transporting string values
chan1 := make(chan string)
chan2 := make(chan string)
//invoking the subroutines with channel variables
go data1(chan1)
go data2(chan2)
//Both case statements wait for data in the chan1 or chan2.
//chan2 gets data first since the delay is only 2 sec in data2().
//So the second case will execute and exits the select block
select {
case x := <-chan1:
fmt.Println(x)
case y := <-chan2:
fmt.Println(y)
}
}
Executarea programului de mai sus va da rezultatul:
from data2()
Aici declaraศia select aศteaptฤ ca datele sฤ fie disponibile pe oricare dintre canale. Data2() adaugฤ date la canal dupฤ un somn de 2 secunde, ceea ce va determina executarea celui de-al doilea caz.
Adฤugaศi un caz implicit la selectare รฎn acelaศi program ศi vedeศi rezultatul. Aici, la atingerea blocului select, dacฤ niciun caz nu are date pregฤtite pe canal, acesta va executa blocul implicit fฤrฤ a aศtepta ca datele sฤ fie disponibile pe orice canal.
package main
import "fmt"
import "time"
//push data to channel with a 4 second delay
func data1(ch chan string) {
time.Sleep(4 * time.Second)
ch <- "from data1()"
}
//push data to channel with a 2 second delay
func data2(ch chan string) {
time.Sleep(2 * time.Second)
ch <- "from data2()"
}
func main() {
//creating channel variables for transporting string values
chan1 := make(chan string)
chan2 := make(chan string)
//invoking the subroutines with channel variables
go data1(chan1)
go data2(chan2)
//Both case statements check for data in chan1 or chan2.
//But data is not available (both routines have a delay of 2 and 4 sec)
//So the default block will be executed without waiting for data in channels.
select {
case x := <-chan1:
fmt.Println(x)
case y := <-chan2:
fmt.Println(y)
default:
fmt.Println("Default case executed")
}
}
Acest program va da rezultatul:
Default case executed
Acest lucru se datoreazฤ faptului cฤ, atunci cรขnd a ajuns blocul de selectare, niciun canal nu avea date de citit. Deci, cazul implicit este executat.
mutex
Mutex este forma scurtฤ pentru excluderea reciprocฤ. Mutex este folosit atunci cรขnd nu doriศi sฤ permiteศi accesarea unei resurse de mai multe subrutine รฎn acelaศi timp. Mutex are 2 metode โ Blocare ศi deblocare. Mutex este conศinut รฎn pachetul de sincronizare. Deci, trebuie sฤ importaศi pachetul de sincronizare. Instrucศiunile care trebuie sฤ fie executate reciproc exclusiv pot fi plasate รฎn interiorul mutex.Lock() ศi mutex.Unlock().
Sฤ รฎnvฤศฤm mutex cu un exemplu care numฤrฤ de cรขte ori este executatฤ o buclฤ. รn acest program ne aศteptฤm ca rutina sฤ ruleze bucla de 10 ori ศi numฤrul este stocat รฎn sumฤ. Apelaศi aceastฤ rutinฤ de 3 ori, astfel รฎncรขt numฤrul total ar trebui sฤ fie 30. Numฤrul este stocat รฎntr-un numฤr global de variabile.
รn primul rรขnd, rulaศi programul fฤrฤ mutex
package main
import "fmt"
import "time"
import "strconv"
import "math/rand"
//declare count variable, which is accessed by all the routine instances
var count = 0
//copies count to temp, do some processing(increment) and store back to count
//random delay is added between reading and writing of count variable
func process(n int) {
//loop incrementing the count by 10
for i := 0; i < 10; i++ {
time.Sleep(time.Duration(rand.Int31n(2)) * time.Second)
temp := count
temp++
time.Sleep(time.Duration(rand.Int31n(2)) * time.Second)
count = temp
}
fmt.Println("Count after i="+strconv.Itoa(n)+" Count:", strconv.Itoa(count))
}
func main() {
//loop calling the process() 3 times
for i := 1; i < 4; i++ {
go process(i)
}
//delay to wait for the routines to complete
time.Sleep(25 * time.Second)
fmt.Println("Final Count:", count)
}
Vezi rezultatul
Count after i=1 Count: 11 Count after i=3 Count: 12 Count after i=2 Count: 13 Final Count: 13
Rezultatul poate fi diferit atunci cรขnd รฎl executaศi, dar rezultatul final nu va fi 30.
Aici ceea ce se รฎntรขmplฤ este cฤ 3 goroutine รฎncearcฤ sฤ mฤreascฤ numฤrul de bucle stocat รฎn numฤrul de variabile. Sฤ presupunem cฤ la un moment dat numฤrul este 5 ศi goroutine1 va creศte numฤrul la 6. Paศii principali includ
Numฤr de copii la temp
Creศteศi temperatura
Stocaศi temperatura รฎnapoi pentru a numฤra
Sฤ presupunem cฤ la scurt timp dupฤ efectuarea pasului 3 de cฤtre goroutine1; o altฤ goroutinฤ ar putea avea o valoare veche, sฤ spunem cฤ 3 face paศii de mai sus ศi stocheazฤ 4 รฎnapoi, ceea ce este greศit. Acest lucru poate fi prevenit prin utilizarea mutex care face ca alte rutine sฤ aศtepte atunci cรขnd o rutinฤ foloseศte deja variabila.
Acum veศi rula programul cu mutex. Aici cei 3 paศi menศionaศi mai sus sunt executaศi รฎntr-un mutex.
package main
import "fmt"
import "time"
import "sync"
import "strconv"
import "math/rand"
//declare a mutex instance
var mu sync.Mutex
//declare count variable, which is accessed by all the routine instances
var count = 0
//copies count to temp, do some processing(increment) and store back to count
//random delay is added between reading and writing of count variable
func process(n int) {
//loop incrementing the count by 10
for i := 0; i < 10; i++ {
time.Sleep(time.Duration(rand.Int31n(2)) * time.Second)
//lock starts here
mu.Lock()
temp := count
temp++
time.Sleep(time.Duration(rand.Int31n(2)) * time.Second)
count = temp
//lock ends here
mu.Unlock()
}
fmt.Println("Count after i="+strconv.Itoa(n)+" Count:", strconv.Itoa(count))
}
func main() {
//loop calling the process() 3 times
for i := 1; i < 4; i++ {
go process(i)
}
//delay to wait for the routines to complete
time.Sleep(25 * time.Second)
fmt.Println("Final Count:", count)
}
Acum ieศirea va fi
Count after i=3 Count: 21 Count after i=2 Count: 28 Count after i=1 Count: 30 Final Count: 30
Aici obศinem rezultatul aศteptat ca rezultat final. Deoarece instrucศiunile de citire, creศtere ศi rescriere a numฤrului sunt executate รฎntr-un mutex.
Eroare de manipulare
Erorile sunt condiศii anormale, cum ar fi รฎnchiderea unui fiศier care nu este deschis, deschiderea unui fiศier care nu existฤ, etc. Funcศiile returneazฤ de obicei erori ca ultima valoare returnatฤ.
Exemplul de mai jos explicฤ mai multe despre eroare.
package main
import "fmt"
import "os"
//function accepts a filename and tries to open it.
func fileopen(name string) {
f, er := os.Open(name)
//er will be nil if the file exists else it returns an error object
if er != nil {
fmt.Println(er)
return
}else{
fmt.Println("file opened", f.Name())
}
}
func main() {
fileopen("invalid.txt")
}
Ieศirea va fi:
open /invalid.txt: no such file or directory
Aici am รฎncercat sฤ deschidem un fiศier inexistent ศi a returnat eroarea variabilei. Dacฤ fiศierul este valid, atunci eroarea va fi nulฤ
Erori personalizate
Folosind aceastฤ funcศie, puteศi crea erori personalizate. Acest lucru se face prin utilizarea New() a pachetului de erori. Vom rescrie programul de mai sus pentru a folosi erorile personalizate.
Rulaศi programul de mai jos
package main
import "fmt"
import "os"
import "errors"
//function accepts a filename and tries to open it.
func fileopen(name string) (string, error) {
f, er := os.Open(name)
//er will be nil if the file exists else it returns an error object
if er != nil {
//created a new error object and returns it
return "", errors.New("Custom error message: File name is wrong")
}else{
return f.Name(),nil
}
}
func main() {
//receives custom error or nil after trying to open the file
filename, error := fileopen("invalid.txt")
if error != nil {
fmt.Println(error)
}else{
fmt.Println("file opened", filename)
}
}
Ieศirea va fi:
Custom error message:File name is wrong
Aici area() returneazฤ aria unui pฤtrat. Dacฤ intrarea este mai micฤ de 1, atunci area() returneazฤ un mesaj de eroare.
Citirea fiศierelor
Fiศierele sunt folosite pentru stocarea datelor. Go ne permite sฤ citim date din fiศiere
Mai รฎntรขi creaศi un fiศier, data.txt, รฎn directorul dvs. actual cu conศinutul de mai jos.
Line one Line two Line three
Acum rulaศi programul de mai jos pentru a vedea cฤ imprimฤ conศinutul รฎntregului fiศier ca rezultat
package main
import "fmt"
import "io/ioutil"
func main() {
data, err := ioutil.ReadFile("data.txt")
if err != nil {
fmt.Println("File reading error", err)
return
}
fmt.Println("Contents of file:", string(data))
}
Aici datele, err := ioutil.ReadFile(โdata.txtโ) citeศte datele ศi returneazฤ o secvenศฤ de octeศi. รn timpul imprimฤrii, acesta este convertit รฎn format ศir.
Scrierea fiศierelor
Veศi vedea asta cu un program
package main
import "fmt"
import "os"
func main() {
f, err := os.Create("file1.txt")
if err != nil {
fmt.Println(err)
return
}
l, err := f.WriteString("Write Line one")
if err != nil {
fmt.Println(err)
f.Close()
return
}
fmt.Println(l, "bytes written")
err = f.Close()
if err != nil {
fmt.Println(err)
return
}
}
Aici este creat un fiศier, test.txt. Dacฤ fiศierul existฤ deja, atunci conศinutul fiศierului este trunchiat. Writeline() este folosit pentru a scrie conศinutul fiศierului. Dupฤ aceea, aศi รฎnchis fiศierul folosind Close().
Cheat Sheet
รn acest tutorial Go, am acoperit,
| Subiect | Descriere | Sintaxฤ |
|---|---|---|
| Tipuri de bazฤ | Numeric, ศir, bool | |
| Variabile | Declaraศi ศi atribuiศi valori variabilelor | var tipul nume_variabilฤ var nume_variabilฤ tip = valoare var nume_variabilฤ1, nume_variabilฤ2 = valoare1, valoare2 nume_variabilฤ := valoare |
| constante | Variabile a cฤror valoare nu poate fi modificatฤ odatฤ ce au fost atribuite | const variabilฤ = valoare |
| Pentru Loop | Executaศi instrucศiuni รฎntr-o buclฤ. | pentru initialisation_expression; expresie_evaluare; expresie_iteraศie{ // una sau mai multe declaraศii } |
| Dacฤ altceva | Este o declaraศie condiศionatฤ | dacฤ condiศia{ // declaraศii_1 } else { // declaraศii_2 } |
| comuta | Declaraศie condiศionatฤ cu mai multe cazuri | schimba expresia { valoarea cazului_1: declaraศii_1 valoarea cazului_2: declaraศii_2 case value_n: declaraศii_n implicit: statements_default } |
| Mulศime | Secvenศฤ de nume de dimensiune fixฤ โโa elementelor de acelaศi tip | arrayname := [dimensiune] tip {value_0,value_1,โฆ,value_size-1} |
| Felie | Porศiune sau segment dintr-o matrice | var slice_name [] type = array_name[start:end] |
| funcลฃii | Bloc de declaraศii care รฎndeplineศte o anumitฤ sarcinฤ | func function_name(parameter_1 type, parameter_n type) return_type { //instrucศiuni } |
| Pachete | Sunt folosite pentru a organiza codul. Mฤreศte lizibilitatea ศi reutilizarea codului | import package_nam |
| Amรขna | Amรขnฤ execuศia unei funcศii pรขnฤ cรขnd funcศia care o conศine terminฤ execuศia | defer function_name(lista_parametri) |
| Pointeri | Stocheazฤ adresa de memorie a unei alte variabile. | var nume_variabilฤ *tip |
| Structure | Tip de date definit de utilizator, care conศine รฎncฤ un element de acelaศi tip sau diferit | tip structname struct { variabilฤ_1 variabilฤ_1_tip variabilฤ_2 variabilฤ_2_tip variabilฤ_n variabilฤ_n_tip } |
| Aplicate | O metodฤ este o funcศie cu un argument receptor | func (variabilฤ tip variabilฤ) methodName(lista_parametri) { } |
| Goroutine | O funcศie care poate rula concomitent cu alte funcศii. | mergeศi numele_funcศiei(lista_parametrilor) |
| Canal | Modul prin care funcศiile pot comunica รฎntre ele. Un mediu pe care o rutinฤ plaseazฤ date ศi este accesatฤ de o altฤ rutinฤ. | Declara: ch := make(chan int) Trimiteศi date cฤtre canal: variabilฤ_canal <- nume_variabilฤ Primiศi de pe canal: nume_variabilฤ := <- variabilฤ_canal |
| Selectaศi | Declaraศie Switch care funcศioneazฤ pe canale. Declaraศiile de caz vor fi o operaศiune de canal. Cรขnd oricare dintre canale este gata cu date, atunci instrucศiunea asociatฤ cu acel caz este executatฤ | Selectaศi { caz x := <-chan1: fmt.Println(x) cazul y := <-chan2: fmt.Println(y) } |
| mutex | Mutex este folosit atunci cรขnd nu doriศi sฤ permiteศi accesarea unei resurse de mai multe subrutine รฎn acelaศi timp. Mutex are 2 metode โ Blocare ศi deblocare | mutex.Lock() //instrucศiuni mutex.Unlock(). |
| Citiศi fiศiere | Citeศte datele ศi returneazฤ o secvenศฤ de octeศi. | Date, err := ioutil.ReadFile(nume fiศier) |
| Scrieศi fiศierul | Scrie date รฎntr-un fiศier | l, err := f.WriteString(text_to_write) |
