Idź - szybki przewodnik

Go to język ogólnego przeznaczenia, zaprojektowany z myślą o programowaniu systemów. Został pierwotnie opracowany w Google w 2007 roku przez Roberta Griesemera, Roba Pike'a i Kena Thompsona. Jest silnie i statycznie typowany, zapewnia wbudowaną obsługę czyszczenia pamięci i obsługuje programowanie współbieżne.

Programy są budowane przy użyciu pakietów, w celu efektywnego zarządzania zależnościami. Implementacje programowania Go używają tradycyjnego modelu kompilacji i łączenia do generowania plików wykonywalnych. Język programowania Go został ogłoszony w listopadzie 2009 roku i jest używany w niektórych systemach produkcyjnych Google.

Funkcje programowania w Go

Najważniejsze funkcje programowania w Go są wymienione poniżej -

  • Wsparcie dla środowiska przyjmującego wzorce podobne do języków dynamicznych. Na przykład wnioskowanie o typie (x: = 0 jest prawidłową deklaracją zmiennej x typu int)

  • Czas kompilacji jest szybki.

  • Wbudowana obsługa współbieżności: lekkie procesy (przez procedury go), kanały, instrukcja select.

  • Programy Go są proste, zwięzłe i bezpieczne.

  • Wsparcie dla interfejsów i osadzania typów.

  • Tworzenie statycznie połączonych natywnych plików binarnych bez zewnętrznych zależności.

Funkcje celowo wyłączone

Aby język był prosty i zwięzły, następujące funkcje powszechnie dostępne w innych podobnych językach zostały pominięte w Go -

  • Obsługa dziedziczenia typów

  • Obsługa przeciążania metod lub operatorów

  • Obsługa zależności cyklicznych między pakietami

  • Wsparcie dla arytmetyki wskaźników

  • Wsparcie dla asercji

  • Wsparcie dla programowania ogólnego

Programy Go

Program Go może mieć długość od 3 do milionów wierszy i powinien być zapisany w jednym lub kilku plikach tekstowych z rozszerzeniem „.go”. Na przykład hello.go.

Możesz użyć "vi", "vim" lub dowolnego innego edytora tekstu, aby zapisać swój program Go do pliku.

Konfiguracja środowiska lokalnego

Jeśli nadal chcesz skonfigurować swoje środowisko dla języka programowania Go, potrzebujesz dwóch następujących programów dostępnych na komputerze -

  • Edytor tekstu
  • Idź kompilator

Edytor tekstu

Będziesz potrzebował edytora tekstu, aby pisać programy. Przykłady edytorów tekstu obejmują Notatnik Windows, polecenie edycji systemu operacyjnego, Brief, Epsilon, EMACS i vim lub vi.

Nazwy i wersje edytorów tekstu mogą się różnić w różnych systemach operacyjnych. Na przykład Notatnik jest używany w systemie Windows, a vim lub vi jest używany w systemie Windows, a także w systemie Linux lub UNIX.

Pliki utworzone za pomocą edytora tekstu nazywane są source files. Zawierają kod źródłowy programu. Pliki źródłowe programów Go zazwyczaj mają rozszerzenie".go".

Przed rozpoczęciem programowania upewnij się, że masz zainstalowany edytor tekstu i masz wystarczające doświadczenie, aby napisać program komputerowy, zapisać go w pliku, skompilować i na koniec wykonać.

Kompilator Go

Kod źródłowy zapisany w pliku źródłowym jest czytelnym dla człowieka źródłem programu. Musi zostać skompilowany i przekształcony w język maszynowy, aby procesor mógł faktycznie wykonać program zgodnie z podanymi instrukcjami. Kompilator języka programowania Go kompiluje kod źródłowy do ostatecznego programu wykonywalnego.

Dystrybucja Go jest instalowana w postaci binarnej dla FreeBSD (wydanie 8 i nowsze), Linux, Mac OS X (Snow Leopard i nowsze) oraz systemów operacyjnych Windows z 32-bitową (386) i 64-bitową (amd64) architekturą procesorów x86.

Poniższa sekcja wyjaśnia, jak zainstalować dystrybucję binarną Go w różnych systemach operacyjnych.

Pobierz Go Archive

Pobierz najnowszą wersję pliku archiwum instalacyjnego Go z Go Downloads . W tym samouczku używana jest następująca wersja: go1.4.windows-amd64.msi .

Jest kopiowany do folderu C: \> go.

OS Nazwa archiwum
Windows go1.4.windows-amd64.msi
Linux go1.4.linux-amd64.tar.gz
Prochowiec go1.4.darwin-amd64-osx10.8.pkg
FreeBSD go1.4.freebsd-amd64.tar.gz

Instalacja na UNIX / Linux / Mac OS X i FreeBSD

Wypakuj archiwum pobierania do folderu / usr / local, tworząc drzewo Go w / usr / local / go. Na przykład -

tar -C / usr / local -xzf go1.4.linux-amd64.tar.gz

Dodaj / usr / local / go / bin do zmiennej środowiskowej PATH.

OS Wynik
Linux export PATH = $ PATH: / usr / local / go / bin
Prochowiec export PATH = $ PATH: / usr / local / go / bin
FreeBSD export PATH = $ PATH: / usr / local / go / bin

Instalacja w systemie Windows

Użyj pliku MSI i postępuj zgodnie z wyświetlanymi instrukcjami, aby zainstalować narzędzia Go. Domyślnie instalator używa dystrybucji Go w katalogu c: \ Go. Instalator powinien ustawić katalog c: \ Go \ bin w zmiennej środowiskowej PATH systemu Windows. Uruchom ponownie wszystkie otwarte monity poleceń, aby zmiana zaczęła obowiązywać.

Weryfikacja instalacji

Utwórz plik go o nazwie test.go in C:\>Go_WorkSpace.

Plik: test.go

package main

import "fmt"

func main() {
   fmt.Println("Hello, World!")
}

Teraz uruchom test.go, aby zobaczyć wynik -

C:\Go_WorkSpace>go run test.go

Wynik

Hello, World!

Zanim przestudiujemy podstawowe elementy składowe języka programowania Go, omówmy najpierw absolutną minimalną strukturę programów Go, abyśmy mogli potraktować ją jako odniesienie w kolejnych rozdziałach.

Przykład Hello World

Program Go składa się zasadniczo z następujących części -

  • Deklaracja pakietu
  • Importuj pakiety
  • Functions
  • Variables
  • Instrukcje i wyrażenia
  • Comments

Spójrzmy na prosty kod, który wypisuje słowa „Hello World” -

package main

import "fmt"

func main() {
   /* This is my first sample program. */
   fmt.Println("Hello, World!")
}

Przyjrzyjmy się różnym częściom powyższego programu -

  • Pierwsza linia pakietu programu main określa nazwę pakietu, w którym ten program powinien się znajdować. Jest to obowiązkowe stwierdzenie, ponieważ programy Go uruchamiane są w pakietach. Główny pakiet jest punktem wyjścia do uruchomienia programu. Każdy pakiet ma powiązaną ścieżkę i nazwę.

  • Następna linia importu "fmt" jest poleceniem preprocesora, które mówi kompilatorowi Go, aby dołączył pliki znajdujące się w pakiecie fmt.

  • Następna linia func main () to główna funkcja, w której rozpoczyna się wykonywanie programu.

  • Następna linia /*...*/ jest ignorowana przez kompilator i służy do dodawania komentarzy w programie. Komentarze są również reprezentowane przy użyciu // podobnych do komentarzy w Javie lub C ++.

  • Następna linia fmt.Println (...) to kolejna funkcja dostępna w Go, która powoduje wyświetlenie komunikatu „Hello, World!” do wyświetlenia na ekranie. Tutaj pakiet fmt wyeksportował metodę Println, która służy do wyświetlania komunikatu na ekranie.

  • Zwróć uwagę na duże P metody Println. W języku Go nazwa jest eksportowana, jeśli zaczyna się wielką literą. Wyeksportowane oznacza, że ​​funkcja lub zmienna / stała jest dostępna dla importera odpowiedniego pakietu.

Wykonywanie programu Go

Omówmy, jak zapisać kod źródłowy w pliku, skompilować go i na koniec wykonać program. Postępuj zgodnie z instrukcjami podanymi poniżej -

  • Otwórz edytor tekstu i dodaj powyższy kod.

  • Zapisz plik jako hello.go

  • Otwórz wiersz polecenia.

  • Przejdź do katalogu, w którym zapisałeś plik.

  • Wpisz go run hello.go i naciśnij klawisz Enter, aby uruchomić kod.

  • Jeśli w kodzie nie ma błędów, zostanie wyświetlony komunikat „Hello World!” wydrukowane na ekranie.

$ go run hello.go
Hello, World!

Upewnij się, że kompilator Go znajduje się w Twojej ścieżce i że uruchamiasz go w katalogu zawierającym plik źródłowy hello.go.

Omówiliśmy podstawową strukturę programu Go w poprzednim rozdziale. Teraz łatwo będzie zrozumieć inne podstawowe elementy składowe języka programowania Go.

Tokeny w Go

Program Go składa się z różnych tokenów. Token jest słowem kluczowym, identyfikatorem, stałą, literałem ciągu lub symbolem. Na przykład następująca instrukcja Go składa się z sześciu tokenów -

fmt.Println("Hello, World!")

Poszczególne żetony to -

fmt
.
Println
(
   "Hello, World!"
)

Separator linii

W programie Go klucz separatora linii jest zakończeniem instrukcji. Oznacza to, że poszczególne instrukcje nie wymagają specjalnego separatora, takiego jak „;” w kompilatorze C. The Go wewnętrznie umieszcza „;” jako terminator instrukcji wskazujący koniec jednej jednostki logicznej.

Na przykład spójrz na następujące stwierdzenia -

fmt.Println("Hello, World!")
fmt.Println("I am in Go Programming World!")

Komentarze

Komentarze są jak teksty pomocnicze w programie Go i są ignorowane przez kompilator. Zaczynają się od / * i kończą znakami * /, jak pokazano poniżej -

/* my first program in Go */

Nie możesz umieszczać komentarzy w komentarzach i nie pojawiają się one w ciągu znaków lub literałów znakowych.

Identyfikatory

Identyfikator Go to nazwa używana do identyfikacji zmiennej, funkcji lub dowolnego innego elementu zdefiniowanego przez użytkownika. Identyfikator zaczyna się od litery od A do Z lub od a do z lub podkreślenia _, po którym następuje zero lub więcej liter, znaków podkreślenia i cyfr (od 0 do 9).

identyfikator = litera {litera | unicode_digit}.

Go nie zezwala na znaki interpunkcyjne, takie jak @, $ i% w identyfikatorach. Go tocase-sensitivejęzyk programowania. Zatem siła robocza i siła robocza to dwa różne identyfikatory w Go. Oto kilka przykładów akceptowanych identyfikatorów -

mahesh      kumar   abc   move_name   a_123
myname50   _temp    j      a23b9      retVal

Słowa kluczowe

Poniższa lista przedstawia słowa zastrzeżone w Go. Te zarezerwowane słowa nie mogą być używane jako stałe, zmienne ani żadne inne nazwy identyfikatorów.

przerwa domyślna func berło Wybierz
walizka odraczać Iść mapa Struct
chan jeszcze Iść do pakiet Przełącznik
konst upadek gdyby zasięg Rodzaj
kontyntynuj dla import powrót Var

Białe spacje w Go

Białe znaki to termin używany w Go do opisywania spacji, tabulatorów, znaków nowej linii i komentarzy. Linia zawierająca tylko białe znaki, prawdopodobnie z komentarzem, jest nazywana pustą linią, a kompilator Go całkowicie ją ignoruje.

Białe spacje oddzielają jedną część instrukcji od drugiej i umożliwiają kompilatorowi zidentyfikowanie, gdzie kończy się jeden element instrukcji, na przykład int, a zaczyna następny element. Dlatego w poniższym oświadczeniu -

var age int;

Aby kompilator mógł je rozróżnić, między int a age musi znajdować się co najmniej jeden biały znak (zwykle spacja). Z drugiej strony w poniższym stwierdzeniu -

fruit = apples + oranges;   // get the total fruit

Pomiędzy owocami a = lub między = a jabłkami nie są potrzebne żadne spacje, chociaż możesz je dodać, jeśli chcesz, aby były czytelne.

W języku programowania Go typy danych odnoszą się do rozbudowanego systemu używanego do deklarowania zmiennych lub funkcji różnych typów. Typ zmiennej określa, ile miejsca zajmuje ona w pamięci i jak jest interpretowany przechowywany wzór bitowy.

Typy w Go można sklasyfikować w następujący sposób -

Sr.No. Rodzaje i opis
1

Boolean types

Są to typy logiczne i składają się z dwóch predefiniowanych stałych: (a) prawda (b) fałsz

2

Numeric types

Ponownie są to typy arytmetyczne i reprezentują a) typy całkowite lub b) wartości zmiennoprzecinkowe w całym programie.

3

String types

Typ ciągu reprezentuje zestaw wartości ciągu. Jego wartość to sekwencja bajtów. Ciągi znaków są niezmiennymi typami, które są tworzone po utworzeniu, nie można zmienić zawartości ciągu. Poprzednio zadeklarowany typ łańcucha to łańcuch.

4

Derived types

Obejmują one (a) typy wskaźników, (b) typy tablic, (c) typy struktur, (d) typy unii oraz (e) typy funkcji f) typy segmentów g) typy interfejsów h) typy map i) typy kanałów

Typy tablic i typy struktur są zbiorczo nazywane aggregate types. Typ funkcji określa zestaw wszystkich funkcji z tymi samymi parametrami i typami wyników. Omówimy podstawowe typy w następnej sekcji, podczas gdy inne typy zostaną omówione w następnych rozdziałach.

Typy całkowite

Wstępnie zdefiniowane typy liczb całkowitych niezależne od architektury to -

Sr.No. Rodzaje i opis
1

uint8

8-bitowe liczby całkowite bez znaku (od 0 do 255)

2

uint16

16-bitowe liczby całkowite bez znaku (od 0 do 65535)

3

uint32

32-bitowe liczby całkowite bez znaku (od 0 do 4294967295)

4

uint64

64-bitowe liczby całkowite bez znaku (od 0 do 18446744073709551615)

5

int8

Podpisane 8-bitowe liczby całkowite (od -128 do 127)

6

int16

Podpisane 16-bitowe liczby całkowite (od -32768 do 32767)

7

int32

Podpisane 32-bitowe liczby całkowite (od -2147483648 do 2147483647)

8

int64

Podpisane 64-bitowe liczby całkowite (od -9223372036854775808 do 9223372036854775807)

Typy pływające

Wstępnie zdefiniowane typy zmiennoprzecinkowe niezależne od architektury to -

Sr.No. Rodzaje i opis
1

float32

IEEE-754 32-bitowe liczby zmiennoprzecinkowe

2

float64

64-bitowe liczby zmiennoprzecinkowe IEEE-754

3

complex64

Liczby zespolone z częściami rzeczywistymi i urojonymi float32

4

complex128

Liczby zespolone z częściami rzeczywistymi i urojonymi float64

Wartość n-bitowej liczby całkowitej wynosi n bitów i jest reprezentowana za pomocą uzupełniających operacji arytmetycznych do dwóch.

Inne typy liczbowe

Istnieje również zestaw typów liczbowych z rozmiarami specyficznymi dla implementacji -

Sr.No. Rodzaje i opis
1

byte

tak samo jak uint8

2

rune

tak samo jak int32

3

uint

32 lub 64 bity

4

int

taki sam rozmiar jak uint

5

uintptr

liczba całkowita bez znaku do przechowywania niezinterpretowanych bitów wartości wskaźnika

Zmienna to nic innego jak nazwa nadana obszarowi pamięci, którym programy mogą manipulować. Każda zmienna w Go ma określony typ, który określa rozmiar i układ pamięci zmiennej, zakres wartości, które mogą być przechowywane w tej pamięci oraz zestaw operacji, które można zastosować do zmiennej.

Nazwa zmiennej może składać się z liter, cyfr i znaku podkreślenia. Musi zaczynać się od litery lub podkreślenia. Wielkie i małe litery są różne, ponieważ w Go jest rozróżniana wielkość liter. W oparciu o podstawowe typy wyjaśnione w poprzednim rozdziale, będą następujące podstawowe typy zmiennych -

Sr.No Typ i opis
1

byte

Zwykle pojedynczy oktet (jeden bajt). To jest typ bajtowy.

2

int

Najbardziej naturalny rozmiar liczby całkowitej dla maszyny.

3

float32

Wartość zmiennoprzecinkowa o pojedynczej precyzji.

Język programowania Go pozwala również na definiowanie różnych innych typów zmiennych, takich jak Enumeration, Pointer, Array, Structure i Union, które omówimy w kolejnych rozdziałach. W tym rozdziale skupimy się tylko na podstawowych typach zmiennych.

Definicja zmiennej w Go

Definicja zmiennej informuje kompilator, gdzie i ile pamięci ma utworzyć dla zmiennej. Definicja zmiennej określa typ danych i zawiera listę co najmniej jednej zmiennej tego typu w następujący sposób -

var variable_list optional_data_type;

Tutaj, optional_data_type jest prawidłowym typem danych Go, w tym bajt, int, float32, complex64, boolean lub dowolny obiekt zdefiniowany przez użytkownika itp. oraz variable_listmoże składać się z jednej lub więcej nazw identyfikatorów oddzielonych przecinkami. Tutaj pokazano kilka ważnych deklaracji -

var  i, j, k int;
var  c, ch byte;
var  f, salary float32;
d =  42;

Twierdzenie “var i, j, k;”deklaruje i definiuje zmienne i, j oraz k; co instruuje kompilator, aby utworzył zmienne o nazwach i, j i k typu int.

Zmienne można zainicjować (przypisać wartość początkową) w ich deklaracji. Typ zmiennej jest automatycznie oceniany przez kompilator na podstawie przekazanej do niej wartości. Inicjator składa się ze znaku równości, po którym następuje stałe wyrażenie w następujący sposób -

variable_name = value;

Na przykład,

d = 3, f = 5;    // declaration of d and f. Here d and f are int

Dla definicji bez inicjatora: zmienne ze statycznym czasem trwania są niejawnie inicjowane z nil (wszystkie bajty mają wartość 0); początkowa wartość wszystkich innych zmiennych jest zerową wartością ich typu danych.

Statyczna deklaracja typu w Go

Deklaracja zmiennej typu statycznego zapewnia kompilatorowi, że dostępna jest jedna zmienna o podanym typie i nazwie, dzięki czemu kompilator może przystąpić do dalszej kompilacji bez wymagania pełnych szczegółów zmiennej. Deklaracja zmiennej ma znaczenie tylko w momencie kompilacji, kompilator potrzebuje faktycznej deklaracji zmiennej w momencie linkowania programu.

Przykład

Wypróbuj poniższy przykład, w którym zmienna została zadeklarowana z typem i zainicjowana wewnątrz funkcji głównej -

package main

import "fmt"

func main() {
   var x float64
   x = 20.0
   fmt.Println(x)
   fmt.Printf("x is of type %T\n", x)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

20
x is of type float64

Dynamiczna deklaracja typu / wnioskowanie o typie w Go

Deklaracja zmiennej typu dynamicznego wymaga, aby kompilator zinterpretował typ zmiennej w oparciu o przekazaną do niej wartość. Kompilator nie wymaga, aby zmienna miała typ statyczny jako wymagany wymóg.

Przykład

Wypróbuj poniższy przykład, w którym zmienne zostały zadeklarowane bez żadnego typu. Zauważ, że w przypadku wnioskowania o typie zainicjowaliśmy zmiennąy gdzie: = operator, podczas gdy x jest inicjowany za pomocą operatora =.

package main

import "fmt"

func main() {
   var x float64 = 20.0

   y := 42 
   fmt.Println(x)
   fmt.Println(y)
   fmt.Printf("x is of type %T\n", x)
   fmt.Printf("y is of type %T\n", y)	
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

20
42
x is of type float64
y is of type int

Deklaracja zmiennych mieszanych w Go

Zmienne różnych typów można deklarować za jednym razem za pomocą wnioskowania o typie.

Przykład

package main

import "fmt"

func main() {
   var a, b, c = 3, 4, "foo"  
	
   fmt.Println(a)
   fmt.Println(b)
   fmt.Println(c)
   fmt.Printf("a is of type %T\n", a)
   fmt.Printf("b is of type %T\n", b)
   fmt.Printf("c is of type %T\n", c)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

3
4
foo
a is of type int
b is of type int
c is of type string

L-wartości i r-wartości w Go

W Go istnieją dwa rodzaje wyrażeń -

  • lvalue- Wyrażenia odnoszące się do miejsca w pamięci nazywane są wyrażeniem „l-wartość”. Wartość l może pojawić się jako lewa lub prawa strona przypisania.

  • rvalue- Termin rvalue odnosi się do wartości danych przechowywanych pod jakimś adresem w pamięci. Wartość r to wyrażenie, któremu nie można przypisać wartości, co oznacza, że ​​wartość r może pojawić się po prawej, ale nie po lewej stronie przypisania.

Zmienne to lvalues, więc mogą pojawiać się po lewej stronie przydziału. Literały numeryczne są wartościami r, więc nie można ich przypisywać i nie mogą pojawiać się po lewej stronie.

Poniższe oświadczenie jest ważne -

x = 20.0

Poniższe stwierdzenie jest nieprawidłowe. Generowałoby to błąd w czasie kompilacji -

10 = 20

Stałe odnoszą się do stałych wartości, których program nie może zmienić podczas wykonywania. Te stałe wartości są również nazywaneliterals.

Stałe mogą mieć dowolny z podstawowych typów danych, takich jak stała całkowita, stała zmiennoprzecinkowa, stała znakowa lub literał ciągu . Istnieją również stałe wyliczania.

Stałe są traktowane jak zwykłe zmienne, z tą różnicą, że ich wartości nie mogą być modyfikowane po ich zdefiniowaniu.

Literały całkowite

Literał liczby całkowitej może być stałą dziesiętną, ósemkową lub szesnastkową. Prefiks określa podstawę lub podstawę: 0x lub 0X dla szesnastkowej, 0 dla ósemkowej i nic dla dziesiętnej.

Literał liczby całkowitej może również mieć sufiks będący kombinacją U i L, odpowiednio dla unsigned i long. Sufiks może być pisany wielką lub małą literą i może mieć dowolną kolejność.

Oto kilka przykładów literałów całkowitych -

212         /* Legal */
215u        /* Legal */
0xFeeL      /* Legal */
078         /* Illegal: 8 is not an octal digit */
032UU       /* Illegal: cannot repeat a suffix */

Poniżej znajdują się inne przykłady różnych typów literałów całkowitych -

85         /* decimal */
0213       /* octal */
0x4b       /* hexadecimal */
30         /* int */
30u        /* unsigned int */
30l        /* long */
30ul       /* unsigned long */

Literały zmiennoprzecinkowe

Literał zmiennoprzecinkowy ma część całkowitą, przecinek dziesiętny, część ułamkową i część wykładniczą. Literały zmiennoprzecinkowe można przedstawiać w postaci dziesiętnej lub wykładniczej.

Przedstawiając przy użyciu postaci dziesiętnej, należy uwzględnić kropkę dziesiętną, wykładnik lub jedno i drugie, a podczas przedstawiania w postaci wykładniczej należy uwzględnić część całkowitą, część ułamkową lub oba te elementy. Podpisany wykładnik jest wprowadzany przez e lub E.

Oto kilka przykładów literałów zmiennoprzecinkowych -

3.14159       /* Legal */
314159E-5L    /* Legal */
510E          /* Illegal: incomplete exponent */
210f          /* Illegal: no decimal or exponent */
.e55          /* Illegal: missing integer or fraction */

Sekwencja ewakuacyjna

Kiedy pewne znaki są poprzedzone odwrotnym ukośnikiem, będą miały specjalne znaczenie w Go. Są to znane jako kody sekwencji ucieczki, które są używane do reprezentowania nowej linii (\ n), tabulacji (\ t), backspace, itp. Tutaj masz listę niektórych takich kodów sekwencji ucieczki -

Sekwencja ewakuacyjna Znaczenie
\\ \ postać
\ ' ' postać
\ " " postać
\? ? postać
\za Alert lub dzwonek
\b Backspace
\fa Form feed
\ n Nowa linia
\ r Powrót karetki
\ t Zakładka pozioma
\ v Zakładka pionowa
\ ooo Liczba ósemkowa składająca się z jednej do trzech cyfr
\ xhh. . . Liczba szesnastkowa składająca się z jednej lub więcej cyfr

Poniższy przykład pokazuje, jak używać \t w programie -

package main

import "fmt"

func main() {
   fmt.Printf("Hello\tWorld!")
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Hello World!

Literały smyczkowe w ruchu

Literały łańcuchowe lub stałe są ujęte w podwójne cudzysłowy „”. Ciąg zawiera znaki podobne do literałów znakowych: zwykłe znaki, sekwencje ucieczki i znaki uniwersalne.

Możesz podzielić długi wiersz na wiele wierszy, używając literałów łańcuchowych i oddzielając je białymi znakami.

Oto kilka przykładów literałów ciągów. Wszystkie trzy formy są identycznymi ciągami.

"hello, dear"

"hello, \

dear"

"hello, " "d" "ear"

Const słowo

Możesz użyć const prefiks do deklarowania stałych o określonym typie w następujący sposób -

const variable type = value;

Poniższy przykład pokazuje, jak używać const słowo kluczowe -

package main

import "fmt"

func main() {
   const LENGTH int = 10
   const WIDTH int = 5   
   var area int

   area = LENGTH * WIDTH
   fmt.Printf("value of area : %d", area)   
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

value of area : 50

Zauważ, że dobrą praktyką programistyczną jest definiowanie stałych WIELKIMI LITERAMI.

Operator to symbol, który mówi kompilatorowi, aby wykonał określone operacje matematyczne lub logiczne. Język Go jest bogaty we wbudowane operatory i zapewnia następujące typy operatorów -

  • Operatory arytmetyczne
  • Operatorzy relacyjni
  • Operatory logiczne
  • Operatory bitowe
  • Operatory przypisania
  • Różni operatorzy

Ten samouczek wyjaśnia po kolei operatory arytmetyczne, relacyjne, logiczne, bitowe, przypisania i inne.

Operatory arytmetyczne

Poniższa tabela przedstawia wszystkie operatory arytmetyczne obsługiwane przez język Go. Przyjmij zmiennąA posiada 10 i zmienną B mieści wtedy 20 -

Pokaż przykłady

Operator Opis Przykład
+ Dodaje dwa operandy A + B daje 30
- Odejmuje drugi operand od pierwszego A - B daje -10
* Mnoży oba operandy A * B daje 200
/ Dzieli licznik przez mianownik. B / A daje 2
% Operator modułu; daje resztę po dzieleniu liczb całkowitych. B% A daje 0
++ Operator przyrostu. Zwiększa wartość całkowitą o jeden. A ++ daje 11
- Operator obniżenia. Zmniejsza wartość całkowitą o jeden. A - daje 9

Operatorzy relacyjni

W poniższej tabeli wymieniono wszystkie operatory relacyjne obsługiwane przez język Go. Przyjmij zmiennąA posiada 10 i zmienną B mieści 20, a następnie -

Pokaż przykłady

Operator Opis Przykład
== Sprawdza, czy wartości dwóch operandów są równe, czy nie; jeśli tak, warunek staje się prawdziwy. (A == B) nie jest prawdą.
! = Sprawdza, czy wartości dwóch operandów są równe, czy nie; jeśli wartości nie są równe, warunek staje się prawdziwy. (A! = B) jest prawdą.
> Sprawdza, czy wartość lewego operandu jest większa niż wartość prawego operandu; jeśli tak, warunek staje się prawdziwy. (A> B) nie jest prawdą.
< Sprawdza, czy wartość lewego operandu jest mniejsza niż wartość prawego operandu; jeśli tak, warunek staje się prawdziwy. (A <B) jest prawdą.
> = Sprawdza, czy wartość lewego operandu jest większa lub równa wartości prawego operandu; jeśli tak, warunek staje się prawdziwy. (A> = B) nie jest prawdą.
<= Sprawdza, czy wartość lewego operandu jest mniejsza lub równa wartości prawego operandu; jeśli tak, warunek staje się prawdziwy. (A <= B) jest prawdą.

Operatory logiczne

W poniższej tabeli wymieniono wszystkie operatory logiczne obsługiwane przez język Go. Przyjmij zmiennąA zawiera 1 i zmienną B posiada 0, a następnie -

Pokaż przykłady

Operator Opis Przykład
&& Nazywany operatorem logicznym AND. Jeśli oba operandy są niezerowe, warunek staje się prawdziwy. (A && B) jest fałszem.
|| Nazywany operatorem logicznym OR. Jeśli którykolwiek z dwóch operandów jest niezerowy, warunek staje się prawdziwy. (A || B) jest prawdą.
! Nazywany operatorem logicznym NOT. Służy do odwracania stanu logicznego operandu. Jeśli warunek jest spełniony, operator logiczny NOT spowoduje fałsz. ! (A && B) jest prawdą.

W poniższej tabeli przedstawiono wszystkie operatory logiczne obsługiwane przez język Go. Przyjmij zmiennąA jest prawdziwe i zmienne B ma fałsz, więc -

Operator Opis Przykład
&& Nazywany operatorem logicznym AND. Jeśli oba operandy są fałszywe, warunek staje się fałszywy. (A && B) jest fałszem.
|| Nazywany operatorem logicznym OR. Jeśli którykolwiek z dwóch operandów jest prawdziwy, warunek staje się prawdziwy. (A || B) jest prawdą.
! Nazywany operatorem logicznym NOT. Służy do odwracania stanu logicznego operandu. Jeśli warunek jest prawdziwy, wówczas operator logiczny NOT sprawi, że będzie on fałszywy. ! (A && B) jest prawdą.

Operatory bitowe

Operatory bitowe pracują na bitach i wykonują operacje bit po bicie. Tabele prawdy dla &, | i ^ są następujące -

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

Załóżmy, że A = 60; i B = 13. W formacie binarnym będą one następujące -

A = 0011 1100

B = 0000 1101

-----------------

A&B = 0000 1100

A | B = 0011 1101

A ^ B = 0011 0001

~ A = 1100 0011

W poniższej tabeli wymieniono operatory bitowe obsługiwane przez język C. Załóżmy, że zmienna A zawiera 60, a zmienna B 13, a następnie -

Pokaż przykłady

Operator Opis Przykład
& Operator binarny AND kopiuje trochę do wyniku, jeśli istnieje w obu operandach. (A i B) da 12, czyli 0000 1100
| Operator binarny OR kopiuje bit, jeśli istnieje w którymkolwiek operandzie. (A | B) da 61, czyli 0011 1101
^ Binarny operator XOR kopiuje bit, jeśli jest ustawiony w jednym operandzie, ale nie w obu. (A ^ B) da 49, czyli 0011 0001
<< Binarny operator przesunięcia w lewo. Wartość lewych operandów jest przesuwana w lewo o liczbę bitów określoną przez prawy operand. << 2 da 240, czyli 1111 0000
>> Binarny operator przesunięcia w prawo. Wartość lewego operandu jest przesuwana w prawo o liczbę bitów określoną przez prawy operand. >> 2 da 15, czyli 0000 1111

Operatory przypisania

W poniższej tabeli wymieniono wszystkie operatory przypisania obsługiwane przez język Go -

Pokaż przykłady

Operator Opis Przykład
= Prosty operator przypisania, przypisuje wartości z operandów po prawej stronie do operandów po lewej stronie C = A + B przypisze wartość A + B do C.
+ = Dodaj operator przypisania AND, dodaje prawy operand do lewego operandu i przypisuje wynik do lewego operandu C + = A jest równoważne C = C + A
- = Operator odejmowania AND przypisania, Odejmuje prawy operand od lewego operandu i przypisuje wynik do lewego operandu C - = A jest równoważne C = C - A
* = Operator mnożenia AND przypisania, Mnoży prawy operand przez lewy operand i przypisuje wynik do lewego operandu C * = A jest równoważne C = C * A
/ = Operator podziału AND przypisania, dzieli lewy operand z prawym operandem i przypisuje wynik do lewego operandu C / = A jest równoważne C = C / A
% = Operator przypisania modułu AND, pobiera moduł przy użyciu dwóch operandów i przypisuje wynik do lewego operandu C% = A jest równoważne C = C% A
<< = Operator przesunięcia w lewo AND przypisania C << = 2 to to samo, co C = C << 2
>> = Operator prawego przesunięcia AND przypisania C >> = 2 to to samo, co C = C >> 2
& = Operator przypisania bitowego AND C & = 2 to to samo, co C = C & 2
^ = bitowe wykluczające OR i operator przypisania C ^ = 2 to to samo, co C = C ^ 2
| = bitowy operator OR i przypisanie C | = 2 to to samo, co C = C | 2

Różni operatorzy

Istnieje kilku innych ważnych operatorów obsługiwanych przez Go Language, w tym sizeof i ?:.

Pokaż przykłady

Operator Opis Przykład
& Zwraca adres zmiennej. &za; podaje rzeczywisty adres zmiennej.
* Wskaźnik do zmiennej. *za; zapewnia wskaźnik do zmiennej.

Pierwszeństwo operatorów w Go

Pierwszeństwo operatorów określa grupowanie terminów w wyrażeniu. Ma to wpływ na sposób oceny wyrażenia. Niektórzy operatorzy mają wyższy priorytet niż inni; na przykład operator mnożenia ma wyższy priorytet niż operator dodawania.

Na przykład x = 7 + 3 * 2; tutaj x ma przypisane 13, a nie 20, ponieważ operator * ma wyższy priorytet niż +, więc najpierw jest mnożony przez 3 * 2, a następnie sumowany do 7.

Tutaj operatory o najwyższym priorytecie pojawiają się na górze tabeli, a operatory o najniższym priorytecie - na dole. W wyrażeniu najpierw zostaną ocenione operatory o wyższym priorytecie.

Pokaż przykłady

Kategoria Operator Łączność
Przyrostek () [] ->. ++ - - Z lewej na prawą
Jednoargumentowe + -! ~ ++ - - (typ) * & sizeof Od prawej do lewej
Mnożny * /% Z lewej na prawą
Przyłączeniowy + - Z lewej na prawą
Zmiana << >> Z lewej na prawą
Relacyjny <<=>> = Z lewej na prawą
Równość ==! = Z lewej na prawą
Bitowe AND & Z lewej na prawą
Bitowe XOR ^ Z lewej na prawą
Bitowe OR | Z lewej na prawą
Logiczne AND && Z lewej na prawą
Logiczne LUB || Z lewej na prawą
Zadanie = + = - = * = / =% = >> = << = & = ^ = | = Od prawej do lewej
Przecinek , Z lewej na prawą

Struktury decyzyjne wymagają, aby programista określił jeden lub więcej warunków, które mają być ocenione lub przetestowane przez program, wraz z instrukcją lub instrukcjami, które mają zostać wykonane, jeśli warunek zostanie określony jako prawdziwy, i opcjonalnie inne instrukcje do wykonania, jeśli warunek jest zdeterminowany, aby być fałszywy.

Poniżej przedstawiono ogólną formę typowej struktury podejmowania decyzji występującej w większości języków programowania -

Język programowania Go zapewnia następujące typy oświadczeń decyzyjnych. Kliknij poniższe łącza, aby sprawdzić ich szczegóły.

Sr.No Oświadczenie i opis
1 jeśli oświadczenie

Na if statement składa się z wyrażenia logicznego, po którym następuje co najmniej jedna instrukcja.

2 if ... else oświadczenie

Na if statement może następować opcjonalnie else statement, która jest wykonywana, gdy wyrażenie logiczne ma wartość false.

3 zagnieżdżone instrukcje if

Możesz użyć jednego if lub else if oświadczenie wewnątrz innego if lub else if sprawozdania).

4 instrukcja przełączania

ZA switch Instrukcja umożliwia testowanie zmiennej pod kątem równości względem listy wartości.

5 instrukcja select

ZA select jest podobne do switch oświadczenie z tą różnicą, że opisy przypadków odnoszą się do komunikacji kanałowej.

Może zaistnieć sytuacja, gdy trzeba będzie kilkakrotnie wykonać blok kodu. Ogólnie instrukcje są wykonywane sekwencyjnie: pierwsza instrukcja funkcji jest wykonywana jako pierwsza, po niej następuje druga i tak dalej.

Języki programowania zapewniają różne struktury kontrolne, które pozwalają na bardziej skomplikowane ścieżki wykonywania.

Instrukcja pętli pozwala nam wielokrotnie wykonać instrukcję lub grupę instrukcji, a następująca po niej jest ogólną postacią instrukcji pętli w większości języków programowania -

Język programowania Go zapewnia następujące typy pętli do obsługi wymagań dotyczących pętli.

Sr.No Typ i opis pętli
1 dla pętli

Wykonuje sekwencję instrukcji wiele razy i skraca kod zarządzający zmienną pętli.

2 pętle zagnieżdżone

To jest jedna lub wiele pętli wewnątrz dowolnej pętli for.

Instrukcje sterowania pętlą

Instrukcje sterujące pętlą zmieniają wykonanie z jego normalnej sekwencji. Gdy wykonanie opuszcza swój zakres, wszystkie automatyczne obiekty, które zostały utworzone w tym zakresie, są niszczone.

Go obsługuje następujące instrukcje sterujące -

Sr.No Oświadczenie i opis kontroli
1 instrukcja break

Kończy for loop lub switch instrukcja i przekazuje wykonanie do instrukcji znajdującej się bezpośrednio po pętli for lub przełączniku.

2 kontynuuj oświadczenie

Powoduje to, że pętla pomija pozostałą część swojego ciała i natychmiast ponownie testuje swój stan przed powtórzeniem.

3 instrukcja goto

Przekazuje kontrolę do oznaczonego wyciągu.

Nieskończona pętla

Pętla staje się nieskończoną pętlą, jeśli jej warunek nigdy nie staje się fałszywy. Do tego celu tradycyjnie używana jest pętla for. Ponieważ żadne z trzech wyrażeń tworzących pętlę for nie jest wymagane, można utworzyć nieskończoną pętlę, pozostawiając wyrażenie warunkowe puste lub przekazując je jako true.

package main

import "fmt"

func main() {
   for true  {
       fmt.Printf("This loop will run forever.\n");
   }
}

W przypadku braku wyrażenia warunkowego przyjmuje się, że jest ono prawdziwe. Możesz mieć wyrażenie inicjujące i inkrementujące, ale programiści C częściej używają konstrukcji for (;;) do oznaczenia nieskończonej pętli.

Note - Możesz zakończyć nieskończoną pętlę, naciskając klawisze Ctrl + C.

Funkcja to grupa instrukcji, które razem wykonują zadanie. Każdy program Go ma co najmniej jedną funkcję, czylimain(). Możesz podzielić swój kod na oddzielne funkcje. Sposób podziału kodu między różne funkcje zależy od Ciebie, ale logicznie rzecz biorąc, podział powinien być taki, aby każda funkcja wykonywała określone zadanie.

Funkcja declarationinformuje kompilator o nazwie funkcji, zwracanym typie i parametrach. Funkcjadefinition dostarcza rzeczywistą treść funkcji.

Biblioteka standardowa Go zawiera wiele wbudowanych funkcji, które program może wywołać. Na przykład functionlen()pobiera argumenty różnych typów i zwraca długość typu. Jeśli przekazano do niego ciąg, funkcja zwraca długość ciągu w bajtach. Jeśli przekazano do niej tablicę, funkcja zwraca długość tablicy.

Funkcje są również znane jako method, sub-routinelub procedure.

Definiowanie funkcji

Ogólna postać definicji funkcji w języku programowania Go jest następująca -

func function_name( [parameter list] ) [return_types]
{
   body of the function
}

Definicja funkcji w języku programowania Go składa się z nagłówka funkcji i treści funkcji . Oto wszystkie części funkcji -

  • Func - Rozpoczyna deklarację funkcji.

  • Function Name- To jest właściwa nazwa funkcji. Nazwa funkcji i lista parametrów razem tworzą podpis funkcji.

  • Parameters- Parametr działa jak symbol zastępczy. Gdy funkcja jest wywoływana, przekazujesz wartość do parametru. Ta wartość jest określana jako rzeczywisty parametr lub argument. Lista parametrów odnosi się do typu, kolejności i liczby parametrów funkcji. Parametry są opcjonalne; to znaczy funkcja może nie zawierać żadnych parametrów.

  • Return Type- Funkcja może zwrócić listę wartości. Return_types to lista typów danych wartości zwracanych przez funkcję. Niektóre funkcje wykonują żądane operacje bez zwracania wartości. W tym przypadku parametr return_type nie jest wymagany.

  • Function Body - Zawiera zbiór instrukcji, które określają, co robi funkcja.

Przykład

Poniższy kod źródłowy przedstawia funkcję o nazwie max(). Ta funkcja przyjmuje dwa parametry num1 i num2 i zwraca maksimum między dwoma -

/* function returning the max between two numbers */
func max(num1, num2 int) int {
   /* local variable declaration */
   result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result 
}

Wywołanie funkcji

Tworząc funkcję Go, podajesz definicję tego, co funkcja ma robić. Aby użyć funkcji, będziesz musiał wywołać tę funkcję, aby wykonać określone zadanie.

Gdy program wywołuje funkcję, sterowanie programem jest przekazywane do wywoływanej funkcji. Wywołana funkcja wykonuje zdefiniowane zadanie i po wykonaniu jej instrukcji return lub po osiągnięciu zamykającego nawiasu zamykającego funkcję zwraca sterowanie programem z powrotem do programu głównego.

Aby wywołać funkcję, wystarczy przekazać wymagane parametry wraz z nazwą funkcji. Jeśli funkcja zwraca wartość, możesz zapisać zwróconą wartość. Na przykład -

package main

import "fmt"

func main() {
   /* local variable definition */
   var a int = 100
   var b int = 200
   var ret int

   /* calling a function to get max value */
   ret = max(a, b)

   fmt.Printf( "Max value is : %d\n", ret )
}

/* function returning the max between two numbers */
func max(num1, num2 int) int {
   /* local variable declaration */
   var result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result 
}

Zachowaliśmy funkcję max () razem z funkcją main () i skompilowaliśmy kod źródłowy. Podczas uruchamiania końcowego pliku wykonywalnego dałoby to następujący wynik -

Max value is : 200

Zwracanie wielu wartości z funkcji

Funkcja Go może zwracać wiele wartości. Na przykład -

package main

import "fmt"

func swap(x, y string) (string, string) {
   return y, x
}
func main() {
   a, b := swap("Mahesh", "Kumar")
   fmt.Println(a, b)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Kumar Mahesh

Argumenty funkcji

Jeśli funkcja ma używać argumentów, musi zadeklarować zmienne, które akceptują wartości argumentów. Te zmienne nazywane sąformal parameters funkcji.

The formal parameters behave like other local variables inside the function and are created upon entry into the function and destroyed upon exit.

While calling a function, there are two ways that arguments can be passed to a function −

Sr.No Call Type & Description
1 Call by value

This method copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument.

2 Call by reference

This method copies the address of an argument into the formal parameter. Inside the function, the address is used to access the actual argument used in the call. This means that changes made to the parameter affect the argument.

By default, Go uses call by value to pass arguments. In general, it means the code within a function cannot alter the arguments used to call the function. The above program, while calling the max() function, used the same method.

Function Usage

A function can be used in the following ways:

Sr.No Function Usage & Description
1 Function as Value

Functions can be created on the fly and can be used as values.

2 Function Closures

Functions closures are anonymous functions and can be used in dynamic programming.

3 Method

Methods are special functions with a receiver.

A scope in any programming is a region of the program where a defined variable can exist and beyond that the variable cannot be accessed. There are three places where variables can be declared in Go programming language −

  • Inside a function or a block (local variables)

  • Outside of all functions (global variables)

  • In the definition of function parameters (formal parameters)

Let us find out what are local and global variables and what are formal parameters.

Local Variables

Variables that are declared inside a function or a block are called local variables. They can be used only by statements that are inside that function or block of code. Local variables are not known to functions outside their own. The following example uses local variables. Here all the variables a, b, and c are local to the main() function.

package main

import "fmt"

func main() {
   /* local variable declaration */
   var a, b, c int 

   /* actual initialization */
   a = 10
   b = 20
   c = a + b

   fmt.Printf ("value of a = %d, b = %d and c = %d\n", a, b, c)
}

When the above code is compiled and executed, it produces the following result −

value of a = 10, b = 20 and c = 30

Zmienne globalne

Zmienne globalne są definiowane poza funkcją, zwykle w górnej części programu. Zmienne globalne zachowują swoją wartość przez cały okres istnienia programu i można uzyskać do nich dostęp w ramach dowolnej funkcji zdefiniowanej dla programu.

Dostęp do zmiennej globalnej można uzyskać za pomocą dowolnej funkcji. Oznacza to, że zmienna globalna jest dostępna do użycia w całym programie po jej zadeklarowaniu. Poniższy przykład używa zmiennych globalnych i lokalnych -

package main

import "fmt"
 
/* global variable declaration */
var g int
 
func main() {
   /* local variable declaration */
   var a, b int

   /* actual initialization */
   a = 10
   b = 20
   g = a + b

   fmt.Printf("value of a = %d, b = %d and g = %d\n", a, b, g)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

value of a = 10, b = 20 and g = 30

Program może mieć taką samą nazwę dla zmiennych lokalnych i globalnych, ale wartość zmiennej lokalnej wewnątrz funkcji ma pierwszeństwo. Na przykład -

package main

import "fmt"
 
/* global variable declaration */
var g int = 20
 
func main() {
   /* local variable declaration */
   var g int = 10
 
   fmt.Printf ("value of g = %d\n",  g)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

value of g = 10

Parametry formalne

Parametry formalne są traktowane jako zmienne lokalne z tą funkcją i mają pierwszeństwo przed zmiennymi globalnymi. Na przykład -

package main

import "fmt"
 
/* global variable declaration */
var a int = 20;
 
func main() {
   /* local variable declaration in main function */
   var a int = 10
   var b int = 20
   var c int = 0

   fmt.Printf("value of a in main() = %d\n",  a);
   c = sum( a, b);
   fmt.Printf("value of c in main() = %d\n",  c);
}
/* function to add two integers */
func sum(a, b int) int {
   fmt.Printf("value of a in sum() = %d\n",  a);
   fmt.Printf("value of b in sum() = %d\n",  b);

   return a + b;
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

value of a in main() = 10
value of a in sum() = 10
value of b in sum() = 20
value of c in main() = 30

Inicjalizacja zmiennych lokalnych i globalnych

Zmienne lokalne i globalne są inicjowane do wartości domyślnych, czyli 0; podczas gdy wskaźniki są inicjalizowane na zero.

Typ danych Początkowa wartość domyślna
int 0
float32 0
wskaźnik zero

Łańcuchy, które są szeroko stosowane w programowaniu w Go, to fragmenty bajtów przeznaczone tylko do odczytu. W języku programowania Go ciągi znaków sąslices. Platforma Go udostępnia różne biblioteki do manipulowania ciągami znaków.

  • unicode
  • regexp
  • strings

Tworzenie ciągów

Najbardziej bezpośrednim sposobem utworzenia ciągu jest napisanie -

var greeting = "Hello world!"

Za każdym razem, gdy napotka literał ciągu w Twoim kodzie, kompilator tworzy obiekt ciągu z jego wartością, w tym przypadku „Hello world!”.

Literał łańcuchowy zawiera prawidłowe sekwencje UTF-8 zwane runami. Ciąg zawiera dowolne bajty.

package main

import "fmt"

func main() {
   var greeting =  "Hello world!"
   
   fmt.Printf("normal string: ")
   fmt.Printf("%s", greeting)
   fmt.Printf("\n")
   fmt.Printf("hex bytes: ")
   
   for i := 0; i < len(greeting); i++ {
       fmt.Printf("%x ", greeting[i])
   }
   fmt.Printf("\n")
   
   const sampleText = "\xbd\xb2\x3d\xbc\x20\xe2\x8c\x98" 
   /*q flag escapes unprintable characters, with + flag it escapses non-ascii 
   characters as well to make output unambigous  
   */
   fmt.Printf("quoted string: ")
   fmt.Printf("%+q", sampleText)
   fmt.Printf("\n")  
}

Dałoby to następujący wynik -

normal string: Hello world!
hex bytes: 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 
quoted string: "\xbd\xb2=\xbc \u2318"

Note - Literał ciągu znaków jest niezmienny, więc po utworzeniu nie można go zmienić.

Długość łańcucha

Metoda len (str) zwraca liczbę bajtów zawartych w literale ciągu.

package main

import "fmt"

func main() {
   var greeting =  "Hello world!"
   
   fmt.Printf("String Length is: ")
   fmt.Println(len(greeting))  
}

Dałoby to następujący wynik -

String Length is : 12

Łączenie ciągów

Pakiet ciągów zawiera metodę join do łączenia wielu ciągów -

strings.Join(sample, " ")

Join łączy elementy tablicy w celu utworzenia pojedynczego ciągu. Drugim parametrem jest separator, który znajduje się pomiędzy elementami tablicy.

Spójrzmy na następujący przykład -

package main

import ("fmt" "math" )"fmt" "strings")

func main() {
   greetings :=  []string{"Hello","world!"}   
   fmt.Println(strings.Join(greetings, " "))
}

Dałoby to następujący wynik -

Hello world!

Język programowania Go zapewnia strukturę danych o nazwie the array, który może przechowywać sekwencyjną kolekcję elementów tego samego typu o stałym rozmiarze. Tablica jest używana do przechowywania kolekcji danych, ale często bardziej przydatne jest myślenie o tablicy jako o zbiorze zmiennych tego samego typu.

Zamiast deklarować pojedyncze zmienne, takie jak liczba0, liczba1, ... i liczba99, deklarujesz jedną zmienną tablicową, taką jak liczby, i używasz liczb [0], liczb [1] i ..., liczb [99] do reprezentowania indywidualne zmienne. Dostęp do określonego elementu w tablicy uzyskuje się za pomocą indeksu.

Wszystkie tablice składają się z ciągłych lokalizacji pamięci. Najniższy adres odpowiada pierwszemu elementowi, a najwyższy adres ostatniemu elementowi.

Deklarowanie tablic

Aby zadeklarować tablicę w Go, programista określa typ elementów i liczbę elementów wymaganych przez tablicę w następujący sposób -

var variable_name [SIZE] variable_type

Nazywa się to tablicą jednowymiarową . PlikarraySize musi być stałą liczbą całkowitą większą od zera i typemoże być dowolnym prawidłowym typem danych Go. Na przykład, aby zadeklarować 10-elementową tablicę o nazwiebalance typu float32, użyj tej instrukcji -

var balance [10] float32

Tutaj, balance to tablica zmiennych, która może pomieścić do 10 liczb zmiennoprzecinkowych.

Inicjowanie tablic

Możesz zainicjować tablicę w Go pojedynczo lub używając pojedynczej instrukcji w następujący sposób -

var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

Liczba wartości w nawiasach klamrowych {} nie może być większa niż liczba elementów, które zadeklarujemy dla tablicy w nawiasach kwadratowych [].

Jeśli pominiesz rozmiar tablicy, zostanie utworzona tablica wystarczająco duża, aby pomieścić inicjalizację. Dlatego jeśli napiszesz -

var balance = []float32{1000.0, 2.0, 3.4, 7.0, 50.0}

Utworzysz dokładnie taką samą tablicę, jak w poprzednim przykładzie. Poniżej znajduje się przykład przypisywania pojedynczego elementu tablicy -

balance[4] = 50.0

Powyższy wyznacza rachunku, numer elementu 5 p w tablicy o wartości 50,0. Wszystkie tablice mają 0 jako indeks pierwszego elementu, który jest również nazywany indeksem bazowym, a ostatni indeks tablicy będzie całkowitym rozmiarem tablicy minus 1. Poniżej znajduje się obrazkowa reprezentacja tej samej tablicy, którą omówiliśmy powyżej -

Dostęp do elementów tablicy

Dostęp do elementu uzyskuje się poprzez indeksowanie nazwy tablicy. Odbywa się to poprzez umieszczenie indeksu elementu w nawiasach kwadratowych po nazwie tablicy. Na przykład -

float32 salary = balance[9]

Powyższe stwierdzenie zajmie 10 th element z tablicy i przypisać wartość do zmiennej wynagrodzenia. Poniżej znajduje się przykład, który będzie wykorzystywał wszystkie wyżej wymienione trzy koncepcje, a mianowicie. deklaracja, przypisanie i dostęp do tablic -

package main

import "fmt"

func main() {
   var n [10]int /* n is an array of 10 integers */
   var i,j int

   /* initialize elements of array n to 0 */         
   for i = 0; i < 10; i++ {
      n[i] = i + 100 /* set element at location i to i + 100 */
   }
   /* output each array element's value */
   for j = 0; j < 10; j++ {
      fmt.Printf("Element[%d] = %d\n", j, n[j] )
   }
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109

Przejdź do tablic w szczegółach

Istnieją ważne pojęcia związane z tablicą, które powinny być jasne dla programisty Go -

Sr.No Koncepcja i opis
1 Tablice wielowymiarowe

Go obsługuje tablice wielowymiarowe. Najprostszą formą tablicy wielowymiarowej jest tablica dwuwymiarowa.

2 Przekazywanie tablic do funkcji

Możesz przekazać do funkcji wskaźnik do tablicy, podając nazwę tablicy bez indeksu.

Wskaźniki w Go są łatwe i przyjemne do nauczenia. Niektóre zadania programowania w Go są łatwiejsze do wykonania za pomocą wskaźników, a innych zadań, takich jak wywołanie przez odniesienie, nie można wykonać bez użycia wskaźników. Dlatego konieczne jest nauczenie się wskaźników, aby zostać doskonałym programistą Go.

Jak wiadomo, każda zmienna jest miejscem w pamięci i każda lokalizacja pamięci ma zdefiniowany adres, do którego można uzyskać dostęp za pomocą operatora ampersand (&), który oznacza adres w pamięci. Rozważ poniższy przykład, w którym zostanie wyświetlony adres zdefiniowanych zmiennych -

package main

import "fmt"

func main() {
   var a int = 10   
   fmt.Printf("Address of a variable: %x\n", &a  )
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Address of a variable: 10328000

Więc zrozumiałeś, czym jest adres pamięci i jak uzyskać do niego dostęp. Zobaczmy teraz, jakie są wskaźniki.

Co to są wskaźniki?

ZA pointerjest zmienną, której wartością jest adres innej zmiennej, tj. bezpośredni adres miejsca w pamięci. Jak w przypadku każdej zmiennej lub stałej, należy zadeklarować wskaźnik, zanim będzie można go użyć do przechowywania adresu zmiennej. Ogólną postacią deklaracji zmiennej wskaźnikowej jest -

var var_name *var-type

Tutaj, typejest typem bazowym wskaźnika; musi to być prawidłowy typ danych C ivar-namejest nazwą zmiennej wskaźnika. Gwiazdka *, której użyłeś do zadeklarowania wskaźnika, to ta sama gwiazdka, której używasz do mnożenia. Jednak w tej instrukcji gwiazdka jest używana do oznaczania zmiennej jako wskaźnika. Poniżej znajduje się prawidłowa deklaracja wskaźnika -

var ip *int        /* pointer to an integer */
var fp *float32    /* pointer to a float */

Rzeczywisty typ danych wartości wszystkich wskaźników, niezależnie od tego, czy są to liczby całkowite, zmiennoprzecinkowe, czy inne, jest taki sam, długa liczba szesnastkowa, która reprezentuje adres pamięci. Jedyną różnicą między wskaźnikami różnych typów danych jest typ danych zmiennej lub stałej, na którą wskazuje wskaźnik.

Jak używać wskaźników?

Jest kilka ważnych operacji, które często wykonujemy za pomocą wskaźników: (a) definiujemy zmienne wskaźnikowe, (b) przypisujemy adres zmiennej do wskaźnika, oraz (c) uzyskujemy dostęp do wartości pod adresem przechowywanym w zmiennej wskaźnikowej .

Wszystkie te operacje są wykonywane przy użyciu operatora jednoargumentowego *, który zwraca wartość zmiennej znajdującej się pod adresem określonym przez jej operand. Poniższy przykład ilustruje sposób wykonywania tych operacji -

package main

import "fmt"

func main() {
   var a int = 20   /* actual variable declaration */
   var ip *int      /* pointer variable declaration */

   ip = &a  /* store address of a in pointer variable*/

   fmt.Printf("Address of a variable: %x\n", &a  )

   /* address stored in pointer variable */
   fmt.Printf("Address stored in ip variable: %x\n", ip )

   /* access the value using the pointer */
   fmt.Printf("Value of *ip variable: %d\n", *ip )
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Address of var variable: 10328000
Address stored in ip variable: 10328000
Value of *ip variable: 20

Brak wskaźników w Go

Kompilator Go przypisuje wartość Nil do zmiennej wskaźnika w przypadku, gdy nie masz dokładnego adresu do przypisania. Odbywa się to w momencie deklaracji zmiennej. Wskaźnik, któremu przypisano nil, nazywany jest anil wskaźnik.

Wskaźnik zerowy jest stałą o wartości zero zdefiniowaną w kilku standardowych bibliotekach. Rozważ następujący program -

package main

import "fmt"

func main() {
   var  ptr *int

   fmt.Printf("The value of ptr is : %x\n", ptr  )
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

The value of ptr is 0

W większości systemów operacyjnych programy nie mają dostępu do pamięci pod adresem 0, ponieważ pamięć ta jest zarezerwowana przez system operacyjny. Jednak adres pamięci 0 ma szczególne znaczenie; sygnalizuje, że wskaźnik nie ma wskazywać dostępnego miejsca w pamięci. Ale zgodnie z konwencją, jeśli wskaźnik zawiera wartość nil (zero), zakłada się, że nie wskazuje niczego.

Aby sprawdzić wskaźnik zerowy, możesz użyć instrukcji if w następujący sposób -

if(ptr != nil)     /* succeeds if p is not nil */
if(ptr == nil)    /* succeeds if p is null */

Szczegółowe wskazówki

Wskaźniki mają wiele, ale prostych koncepcji i są bardzo ważne w programowaniu w Go. Następujące pojęcia wskaźników powinny być jasne dla programisty Go -

Sr.No Koncepcja i opis
1 Idź - tablica wskaźników

Możesz zdefiniować tablice do przechowywania wielu wskaźników.

2 Idź - wskaźnik do wskaźnika

Idź pozwala mieć wskaźnik na wskaźniku i tak dalej.

3 Przekazywanie wskaźników do funkcji w Go

Przekazywanie argumentu przez odwołanie lub przez adres umożliwia zmianę przekazanego argumentu w funkcji wywołującej przez wywoływaną funkcję.

Tablice Go umożliwiają definiowanie zmiennych, które mogą zawierać kilka elementów danych tego samego rodzaju. Structure to kolejny typ danych zdefiniowany przez użytkownika dostępny w programowaniu Go, który umożliwia łączenie elementów danych różnego rodzaju.

Struktury służą do reprezentowania rekordu. Przypuśćmy, że chcesz śledzić książki w bibliotece. Możesz chcieć śledzić następujące atrybuty każdej książki -

  • Title
  • Author
  • Subject
  • Identyfikator książki

W takim scenariuszu struktury są bardzo przydatne.

Definiowanie struktury

Aby zdefiniować strukturę, musisz użyć type i structsprawozdania. Instrukcja struct definiuje nowy typ danych z wieloma członkami programu. Instrukcja type wiąże nazwę z typem, który jest w naszym przypadku strukturą. Format instrukcji struct jest następujący -

type struct_variable_type struct {
   member definition;
   member definition;
   ...
   member definition;
}

Po zdefiniowaniu typu struktury można go użyć do deklarowania zmiennych tego typu przy użyciu następującej składni.

variable_name := structure_variable_type {value1, value2...valuen}

Dostęp do członków struktury

Aby uzyskać dostęp do dowolnego elementu członkowskiego struktury, używamy rozszerzenia member access operator (.).Operator dostępu do elementu jest zakodowany jako okres między nazwą zmiennej strukturalnej a elementem struktury, do którego chcemy uzyskać dostęp. Użyłbyśstructsłowo kluczowe do definiowania zmiennych typu konstrukcji. Poniższy przykład wyjaśnia, jak używać struktury -

package main

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}
func main() {
   var Book1 Books    /* Declare Book1 of type Book */
   var Book2 Books    /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = "Go Programming"
   Book1.author = "Mahesh Kumar"
   Book1.subject = "Go Programming Tutorial"
   Book1.book_id = 6495407

   /* book 2 specification */
   Book2.title = "Telecom Billing"
   Book2.author = "Zara Ali"
   Book2.subject = "Telecom Billing Tutorial"
   Book2.book_id = 6495700
 
   /* print Book1 info */
   fmt.Printf( "Book 1 title : %s\n", Book1.title)
   fmt.Printf( "Book 1 author : %s\n", Book1.author)
   fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
   fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)

   /* print Book2 info */
   fmt.Printf( "Book 2 title : %s\n", Book2.title)
   fmt.Printf( "Book 2 author : %s\n", Book2.author)
   fmt.Printf( "Book 2 subject : %s\n", Book2.subject)
   fmt.Printf( "Book 2 book_id : %d\n", Book2.book_id)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Book 1 title      : Go Programming
Book 1 author     : Mahesh Kumar
Book 1 subject    : Go Programming Tutorial
Book 1 book_id    : 6495407
Book 2 title      : Telecom Billing
Book 2 author     : Zara Ali
Book 2 subject    : Telecom Billing Tutorial
Book 2 book_id    : 6495700

Struktury jako argumenty funkcji

Możesz przekazać strukturę jako argument funkcji w bardzo podobny sposób, jak przekazujesz dowolną inną zmienną lub wskaźnik. Dostęp do zmiennych strukturalnych uzyskasz w taki sam sposób, jak w powyższym przykładzie -

package main

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}
func main() {
   var Book1 Books    /* Declare Book1 of type Book */
   var Book2 Books    /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = "Go Programming"
   Book1.author = "Mahesh Kumar"
   Book1.subject = "Go Programming Tutorial"
   Book1.book_id = 6495407

   /* book 2 specification */
   Book2.title = "Telecom Billing"
   Book2.author = "Zara Ali"
   Book2.subject = "Telecom Billing Tutorial"
   Book2.book_id = 6495700
 
   /* print Book1 info */
   printBook(Book1)

   /* print Book2 info */
   printBook(Book2)
}
func printBook( book Books ) {
   fmt.Printf( "Book title : %s\n", book.title);
   fmt.Printf( "Book author : %s\n", book.author);
   fmt.Printf( "Book subject : %s\n", book.subject);
   fmt.Printf( "Book book_id : %d\n", book.book_id);
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Book title     : Go Programming
Book author    : Mahesh Kumar
Book subject   : Go Programming Tutorial
Book book_id   : 6495407
Book title     : Telecom Billing
Book author    : Zara Ali
Book subject   : Telecom Billing Tutorial
Book book_id   : 6495700

Wskaźniki do struktur

Możesz zdefiniować wskaźniki do struktur w taki sam sposób, jak definiujesz wskaźnik do dowolnej innej zmiennej w następujący sposób -

var struct_pointer *Books

Teraz możesz zapisać adres zmiennej strukturalnej w zdefiniowanej powyżej zmiennej wskaźnikowej. Aby znaleźć adres zmiennej strukturalnej, umieść operator & przed nazwą struktury w następujący sposób -

struct_pointer = &Book1;

Aby uzyskać dostęp do elementów struktury za pomocą wskaźnika do tej struktury, należy użyć znaku „.” operator w następujący sposób -

struct_pointer.title;

Przepiszmy powyższy przykład za pomocą wskaźnika struktury -

package main

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}
func main() {
   var Book1 Books   /* Declare Book1 of type Book */
   var Book2 Books   /* Declare Book2 of type Book */
 
   /* book 1 specification */
   Book1.title = "Go Programming"
   Book1.author = "Mahesh Kumar"
   Book1.subject = "Go Programming Tutorial"
   Book1.book_id = 6495407

   /* book 2 specification */
   Book2.title = "Telecom Billing"
   Book2.author = "Zara Ali"
   Book2.subject = "Telecom Billing Tutorial"
   Book2.book_id = 6495700
 
   /* print Book1 info */
   printBook(&Book1)

   /* print Book2 info */
   printBook(&Book2)
}
func printBook( book *Books ) {
   fmt.Printf( "Book title : %s\n", book.title);
   fmt.Printf( "Book author : %s\n", book.author);
   fmt.Printf( "Book subject : %s\n", book.subject);
   fmt.Printf( "Book book_id : %d\n", book.book_id);
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Book title     : Go Programming
Book author    : Mahesh Kumar
Book subject   : Go Programming Tutorial
Book book_id   : 6495407
Book title     : Telecom Billing
Book author    : Zara Ali
Book subject   : Telecom Billing Tutorial
Book book_id   : 6495700

Go Slice to abstrakcja dotycząca Go Array. Go Array umożliwia definiowanie zmiennych, które mogą przechowywać kilka elementów danych tego samego rodzaju, ale nie zapewnia żadnej wbudowanej metody dynamicznego zwiększania jej rozmiaru lub uzyskiwania własnej podtablicy. Plasterki pokonują to ograniczenie. Zapewnia wiele funkcji narzędziowych wymaganych w Array i jest szeroko stosowany w programowaniu w Go.

Definiowanie plastra

Aby zdefiniować wycinek, możesz zadeklarować go jako tablicę bez określania jego rozmiaru. Alternatywnie możesz użyćmake funkcja tworzenia plasterka.

var numbers []int /* a slice of unspecified size */
/* numbers == []int{0,0,0,0,0}*/
numbers = make([]int,5,5) /* a slice of length 5 and capacity 5*/

Funkcje len () i cap ()

Wycinek jest abstrakcją nad tablicą. W rzeczywistości wykorzystuje tablice jako podstawową strukturę. Pliklen() funkcja zwraca elementy obecne w wycinku, w którym cap()funkcja zwraca pojemność wycinka (tj. ile elementów może pomieścić). Poniższy przykład wyjaśnia użycie plastra -

package main

import "fmt"

func main() {
   var numbers = make([]int,3,5)
   printSlice(numbers)
}
func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

len = 3 cap = 5 slice = [0 0 0]

Brak plastra

Jeśli wycinek jest zadeklarowany bez danych wejściowych, to domyślnie jest inicjowany jako zero. Jego długość i pojemność są zerowe. Na przykład -

package main

import "fmt"

func main() {
   var numbers []int
   printSlice(numbers)
   
   if(numbers == nil){
      fmt.Printf("slice is nil")
   }
}
func printSlice(x []int){
   fmt.Printf("len = %d cap = %d slice = %v\n", len(x), cap(x),x)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

len = 0 cap = 0 slice = []
slice is nil

Podlicowanie

Slice pozwala określić dolną i górną granicę, aby uzyskać jej podrzędną granicę za pomocą[lower-bound:upper-bound]. Na przykład -

package main

import "fmt"

func main() {
   /* create a slice */
   numbers := []int{0,1,2,3,4,5,6,7,8}   
   printSlice(numbers)
   
   /* print the original slice */
   fmt.Println("numbers ==", numbers)
   
   /* print the sub slice starting from index 1(included) to index 4(excluded)*/
   fmt.Println("numbers[1:4] ==", numbers[1:4])
   
   /* missing lower bound implies 0*/
   fmt.Println("numbers[:3] ==", numbers[:3])
   
   /* missing upper bound implies len(s)*/
   fmt.Println("numbers[4:] ==", numbers[4:])
   
   numbers1 := make([]int,0,5)
   printSlice(numbers1)
   
   /* print the sub slice starting from index 0(included) to index 2(excluded) */
   number2 := numbers[:2]
   printSlice(number2)
   
   /* print the sub slice starting from index 2(included) to index 5(excluded) */
   number3 := numbers[2:5]
   printSlice(number3)
   
}
func printSlice(x []int){
   fmt.Printf("len = %d cap = %d slice = %v\n", len(x), cap(x),x)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

len = 9 cap = 9 slice = [0 1 2 3 4 5 6 7 8]
numbers == [0 1 2 3 4 5 6 7 8]
numbers[1:4] == [1 2 3]
numbers[:3] == [0 1 2]
numbers[4:] == [4 5 6 7 8]
len = 0 cap = 5 slice = []
len = 2 cap = 9  slice = [0 1]
len = 3 cap = 7 slice = [2 3 4]

Funkcje append () i copy ()

Można zwiększyć pojemność plastra za pomocą append()funkcjonować. Za pomocącopy()funkcja, zawartość wycinka źródłowego jest kopiowana do wycinka docelowego. Na przykład -

package main

import "fmt"

func main() {
   var numbers []int
   printSlice(numbers)
   
   /* append allows nil slice */
   numbers = append(numbers, 0)
   printSlice(numbers)
   
   /* add one element to slice*/
   numbers = append(numbers, 1)
   printSlice(numbers)
   
   /* add more than one element at a time*/
   numbers = append(numbers, 2,3,4)
   printSlice(numbers)
   
   /* create a slice numbers1 with double the capacity of earlier slice*/
   numbers1 := make([]int, len(numbers), (cap(numbers))*2)
   
   /* copy content of numbers to numbers1 */
   copy(numbers1,numbers)
   printSlice(numbers1)   
}
func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

len = 0 cap = 0 slice = []
len = 1 cap = 2 slice = [0]
len = 2 cap = 2 slice = [0 1]
len = 5 cap = 8 slice = [0 1 2 3 4]
len = 5 cap = 16 slice = [0 1 2 3 4]

Plik range słowo kluczowe jest używane w forpętla do iteracji po elementach tablicy, wycinka, kanału lub mapy. W przypadku tablicy i plasterków zwraca indeks elementu jako liczbę całkowitą. W przypadku map zwraca klucz następnej pary klucz-wartość. Zakres zwraca jedną wartość lub dwie. Jeśli po lewej stronie wyrażenia zakresu używana jest tylko jedna wartość, jest to pierwsza wartość w poniższej tabeli.

Wyrażenie zakresu 1 wartość 2. wartość (opcjonalnie)
Szyk lub wycinek a [n] E indeks i int a [i] E
Łańcuch typu string indeks i int rune int
mapa m mapa [K] V klucz k K wartość m [k] V
kanał c chan E. element e E. Żaden

Przykład

Poniższy akapit pokazuje, jak używać zakresu -

package main

import "fmt"

func main() {
   /* create a slice */
   numbers := []int{0,1,2,3,4,5,6,7,8} 
   
   /* print the numbers */
   for i:= range numbers {
      fmt.Println("Slice item",i,"is",numbers[i])
   }
   
   /* create a map*/
   countryCapitalMap := map[string] string {"France":"Paris","Italy":"Rome","Japan":"Tokyo"}
   
   /* print map using keys*/
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
   
   /* print map using key-value*/
   for country,capital := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",capital)
   }
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Slice item 0 is 0
Slice item 1 is 1
Slice item 2 is 2
Slice item 3 is 3
Slice item 4 is 4
Slice item 5 is 5
Slice item 6 is 6
Slice item 7 is 7
Slice item 8 is 8
Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo

Go udostępnia inny ważny typ danych o nazwie map, który odwzorowuje unikalne klucze na wartości. Klucz to obiekt, którego używasz do pobrania wartości w późniejszym terminie. Mając klucz i wartość, możesz zapisać wartość w obiekcie Map. Po zapisaniu wartości można ją odzyskać, używając jej klucza.

Definiowanie mapy

Musisz użyć make funkcja tworzenia mapy.

/* declare a variable, by default map will be nil*/
var map_variable map[key_data_type]value_data_type

/* define the map as nil map can not be assigned any value*/
map_variable = make(map[key_data_type]value_data_type)

Przykład

Poniższy przykład ilustruje sposób tworzenia i używania mapy -

package main

import "fmt"

func main() {
   var countryCapitalMap map[string]string
   /* create a map*/
   countryCapitalMap = make(map[string]string)
   
   /* insert key-value pairs in the map*/
   countryCapitalMap["France"] = "Paris"
   countryCapitalMap["Italy"] = "Rome"
   countryCapitalMap["Japan"] = "Tokyo"
   countryCapitalMap["India"] = "New Delhi"
   
   /* print map using keys*/
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
   
   /* test if entry is present in the map or not*/
   capital, ok := countryCapitalMap["United States"]
   
   /* if ok is true, entry is present otherwise entry is absent*/
   if(ok){
      fmt.Println("Capital of United States is", capital)  
   } else {
      fmt.Println("Capital of United States is not present") 
   }
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Capital of India is New Delhi
Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of United States is not present

delete () Funkcja

Funkcja delete () służy do usuwania wpisu z mapy. Wymaga mapy i odpowiedniego klucza, który ma zostać usunięty. Na przykład -

package main

import "fmt"

func main() {   
   /* create a map*/
   countryCapitalMap := map[string] string {"France":"Paris","Italy":"Rome","Japan":"Tokyo","India":"New Delhi"}
   
   fmt.Println("Original map")   
   
   /* print map */
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
   
   /* delete an entry */
   delete(countryCapitalMap,"France");
   fmt.Println("Entry for France is deleted")  
   
   fmt.Println("Updated map")   
   
   /* print map */
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Original Map
Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of India is New Delhi
Entry for France is deleted
Updated Map
Capital of India is New Delhi
Capital of Italy is Rome
Capital of Japan is Tokyo

Rekurencja to proces powtarzania elementów w podobny sposób. Ta sama koncepcja dotyczy również języków programowania. Jeśli program umożliwia wywołanie funkcji wewnątrz tej samej funkcji, wówczas nazywa się to wywołaniem funkcji rekurencyjnej. Spójrz na następujący przykład -

func recursion() {
   recursion() /* function calls itself */
}
func main() {
   recursion()
}

Język programowania Go obsługuje rekursję. Oznacza to, że pozwala funkcji wywoływać samą siebie. Ale używając rekurencji, programiści muszą uważać, aby zdefiniować warunek wyjścia z funkcji, w przeciwnym razie stanie się nieskończoną pętlą.

Przykłady rekursji w Go

Funkcje rekurencyjne są bardzo przydatne do rozwiązywania wielu problemów matematycznych, takich jak obliczanie silni liczby, generowanie szeregów Fibonacciego itp.

Przykład 1: Obliczanie silni za pomocą rekursji w Go

Poniższy przykład oblicza silnię podanej liczby przy użyciu funkcji rekurencyjnej -

package main

import "fmt"

func factorial(i int)int {
   if(i <= 1) {
      return 1
   }
   return i * factorial(i - 1)
}
func main() { 
   var i int = 15
   fmt.Printf("Factorial of %d is %d", i, factorial(i))
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Factorial of 15 is 1307674368000

Przykład 2: Szeregi Fibonacciego wykorzystujące rekursję w Go

Poniższy przykład pokazuje, jak wygenerować szereg Fibonacciego o podanej liczbie przy użyciu funkcji rekurencyjnej -

package main

import "fmt"

func fibonaci(i int) (ret int) {
   if i == 0 {
      return 0
   }
   if i == 1 {
      return 1
   }
   return fibonaci(i-1) + fibonaci(i-2)
}
func main() {
   var i int
   for i = 0; i < 10; i++ {
      fmt.Printf("%d ", fibonaci(i))
   }
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

0 1 1 2 3 5 8 13 21 34

Rzutowanie typu to sposób na przekonwertowanie zmiennej z jednego typu danych na inny typ danych. Na przykład, jeśli chcesz zapisać długą wartość w prostej liczbie całkowitej, możesz wpisać rzut long na int. Możesz konwertować wartości z jednego typu na inny przy użyciucast operator. Jego składnia jest następująca -

type_name(expression)

Przykład

Rozważmy następujący przykład, w którym operator rzutowania powoduje, że dzielenie jednej zmiennej całkowitej przez inną jest wykonywane jako operacja na liczbach zmiennoprzecinkowych.

package main

import "fmt"

func main() {
   var sum int = 17
   var count int = 5
   var mean float32
   
   mean = float32(sum)/float32(count)
   fmt.Printf("Value of mean : %f\n",mean)
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Value of mean : 3.400000

Programowanie Go udostępnia inny typ danych o nazwie interfacesktóry reprezentuje zestaw sygnatur metod. Typ danych struct implementuje te interfejsy, aby mieć definicje metod dla sygnatur metod interfejsów.

Składnia

/* define an interface */
type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
   method_name3 [return_type]
   ...
   method_namen [return_type]
}

/* define a struct */
type struct_name struct {
   /* variables */
}

/* implement interface methods*/
func (struct_name_variable struct_name) method_name1() [return_type] {
   /* method implementation */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
   /* method implementation */
}

Przykład

package main

import (
   "fmt" 
   "math" 
)

/* define an interface */
type Shape interface {
   area() float64
}

/* define a circle */
type Circle struct {
   x,y,radius float64
}

/* define a rectangle */
type Rectangle struct {
   width, height float64
}

/* define a method for circle (implementation of Shape.area())*/
func(circle Circle) area() float64 {
   return math.Pi * circle.radius * circle.radius
}

/* define a method for rectangle (implementation of Shape.area())*/
func(rect Rectangle) area() float64 {
   return rect.width * rect.height
}

/* define a method for shape */
func getArea(shape Shape) float64 {
   return shape.area()
}

func main() {
   circle := Circle{x:0,y:0,radius:5}
   rectangle := Rectangle {width:10, height:5}
   
   fmt.Printf("Circle area: %f\n",getArea(circle))
   fmt.Printf("Rectangle area: %f\n",getArea(rectangle))
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Circle area: 78.539816
Rectangle area: 50.000000

Programowanie w Go zapewnia dość prostą strukturę obsługi błędów z wbudowanym typem interfejsu błędu o następującej deklaracji -

type error interface {
   Error() string
}

Funkcje normalnie zwracają błąd jako ostatnią zwracaną wartość. Posługiwać sięerrors.New skonstruować podstawowy komunikat o błędzie w następujący sposób -

func Sqrt(value float64)(float64, error) {
   if(value < 0){
      return 0, errors.New("Math: negative number passed to Sqrt")
   }
   return math.Sqrt(value), nil
}

Użyj wartości zwracanej i komunikatu o błędzie.

result, err:= Sqrt(-1)

if err != nil {
   fmt.Println(err)
}

Przykład

package main

import "errors"
import "fmt"
import "math"

func Sqrt(value float64)(float64, error) {
   if(value < 0){
      return 0, errors.New("Math: negative number passed to Sqrt")
   }
   return math.Sqrt(value), nil
}
func main() {
   result, err:= Sqrt(-1)

   if err != nil {
      fmt.Println(err)
   } else {
      fmt.Println(result)
   }
   
   result, err = Sqrt(9)

   if err != nil {
      fmt.Println(err)
   } else {
      fmt.Println(result)
   }
}

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Math: negative number passed to Sqrt
3