"Bądź skrybą! Oszczędza ci pracy i chroni przed wszelkimi pracami. Oszczędza ci używania motyki i kilofa … skryba, on kieruje wszystkimi pracami w tej krainie!" -
Pierwsze kroki z Go
Go to język programowania ogólnego przeznaczenia stworzony z myślą o programowaniu systemów. Został wynaleziony w 2007 roku przez Roberta Griesemera z Google, Roba Pike′a i Kena Thompsona. Jest silnie i statycznie typowany, ma wbudowaną obsługę wyrzucania elementów bezużytecznych i obsługuje programowanie współbieżne. Pakiety są używane do konstruowania programów do efektywnego zarządzania zależnościami. Implementacje programistyczne Go wykorzystują tradycyjny model kompilacji i łączenia do generowania wykonywalnych plików binarnych. Język programowania Go został wprowadzony w listopadzie 2009 roku i jest obecnie używany w niektórych systemach produkcyjnych Google.
PROGRAMOWANIE FUNKCJI
o Projektowanie języka: projektanci języka podjęli świadomą decyzję, aby język był prosty i łatwy do zrozumienia. Wszystkie szczegóły zawarte są na kilku stronach, a kilka interesujących decyzji projektowych zostało podjętych przy użyciu obiektowego wsparcia języka. Język jest uparty, zalecając konwersacyjną metodę osiągania rzeczy. Kompozycja jest preferowana nad dziedziczeniem. Mantra w Go Language brzmi "Zrób więcej za mniej".
o Zarządzanie pakietami: Go zawiera nowoczesne przepływy pracy programistów do pracy z projektami Open Source do zarządzania zewnętrznymi pakietami. Wsparcie dla pobierania pakietów zewnętrznych i publikowania naszych pakietów jest zapewniane bezpośrednio w narzędziu za pomocą zestawu prostych poleceń.
o Potężna biblioteka standardowa: Go ma solidną bibliotekę standardową, dystrybuowaną w formie pakietów.
o Typowanie statyczne: Go to język z typowaniem statycznym. W rezultacie ten kompilator nie tylko pomyślnie kompiluje kod, ale także zapewnia konwersje typów i kompatybilność. Dzięki tej funkcji Go pozwala uniknąć wszystkich problemów, które obserwujemy w językach o dynamicznym typowaniu.
o Obsługa testów: Go zawiera domyślnie funkcje testów jednostkowych, takie jak prosty mechanizm pisania testów jednostkowych równolegle z naszym kodem, co pozwala nam zrozumieć pokrycie kodu przez nasze testy. Na przykład możemy łatwo użyć tego do wygenerowania dokumentacji kodu.
o Niezależność platformy: podobnie jak język Java, język Go obsługuje niezależność platformy. Ze względu na swoją modułową konstrukcję i modułowość kod jest kompilowany i konwertowany do postaci binarnej, która jest tak mała, jak to tylko możliwe i nie wymaga zależności. Jego kod można skompilować na dowolnej platformie, serwerze lub aplikacji, na której pracujemy.
DLACZEGO GoLang JEST LEPSZY OD INNYCH JĘZYKÓW PROGRAMOWANIA?
W świecie języków programowania nie ma wytchnienia dla innowacji i przełomów. Deweloperzy nieustannie poszukują prostszego, wyrafinowanego i przyjaznego projektom języka. GoLang pojawił się jako niesamowity nowy język programowania z mnóstwem rozwiązań. GoLang od samego początku zaskoczył świat programowania. Tutaj ujawnionych zostanie wiele niespodzianek, które wyróżniają ten język spośród innych. Zacznijmy od przeglądu podstawowych funkcji w skrócie.
Podstawowe możliwości GoLang
Podobno programiści Google wymyślili GoLang, czekając na projekt kompilacji kodu. Właśnie dlatego GoLang jest jedynym językiem, który łączy w sobie wszystkie trzy pożądane cechy, a mianowicie łatwość kodowania, wydajną kompilację kodu i wydajne wykonanie. Fakt, że można połączyć wszystkie te możliwości w jednym języku, odróżnia GoLang od innych języków programowania. Go, znany również jako GoLang, to solidny język systemowy używany do programowania w dużych serwerach sieciowych i dużych systemach rozproszonych. Mówiąc prościej, w kontekście tego, czego Google wymagał od swoich serwerów sieciowych i systemów rozproszonych, GoLang pojawił się jako alternatywa dla C++ i Javy dla twórców aplikacji. Język został zaprojektowany w celu wyeliminowania powolności i trudności związanych z programowaniem dużych i skalowalnych serwerów i systemów oprogramowania. Mówiąc dokładniej, Go przybył do Google, aby zapewnić następujące rozwiązania:
o Kompilacja i wykonanie w mgnieniu oka.
o Wyeliminowanie konieczności pracy z różnymi podzbiorami języków dla jednego projektu.
o Poprawiona czytelność kodu i dokumentacji.
o Zapewnienie całkowicie spójnego języka.
o Umożliwienie prostego wersjonowania programów.
o Możliwość rozwoju w wielu językach.
o Ułatwienie zarządzania zależnościami.
Wielowątkowość i współbieżność
Ponieważ sprzęt staje się z czasem coraz bardziej wyrafinowany, producenci dodają do systemu rdzenie, aby poprawić wydajność. W przypadku ogromnej liczby rdzeni system musi utrzymywać połączenia z bazą danych za pośrednictwem mikroserwisów, zarządzać kolejkami i utrzymywać pamięci podręczne. Właśnie dlatego dzisiejszy sprzęt wymaga języka programowania, który może lepiej obsługiwać współbieżność i zwiększać wydajność w miarę wzrostu liczby rdzeni w miarę upływu czasu. Podczas pracy z wieloma wątkami, większość języków programowania ma brak równoczesnego wykonywania, co często spowalnia tempo programowania, kompilacji i wykonywania. W tym miejscu Go wyłania się jako najbardziej realna opcja do obsługi zarówno wielowątkowości, jak i współbieżności. Kiedy wielordzeniowe procesory były powszechnie dostępne na zaawansowanym sprzęcie, powstał Go jako język programowania. Oczywiście twórcy Go postawili na współbieżność. Go używa goroutines zamiast wątków, co pozwala na jednoczesną obsługę wielu zadań.
Go wzmacnia sprzęt od wewnątrz
Ponieważ procesory sprzętowe rozumieją tylko pliki binarne, każda aplikacja napisana w języku Java lub JVM jest interpretowana jako pliki binarne. Taka interpretacja na poziomie sprzętowym wydłuża czas wykonania. Właśnie dlatego języki kompilowane, takie jak C/C++, które eliminują etap zrozumienia, mogą poprawić wydajność i szybkość wykonywania. Jednak wyodrębnianie i przydzielanie zmiennych w C/C++ wiąże się ze znaczną ilością komplikacji i czasu. W tym miejscu Go błyszczy jako idealne rozwiązanie, łącząc najlepsze z obu światów. Go, podobnie jak C/C++, jest językiem kompilowanym, co sprawia, że jest równie szybki jak oni. Z drugiej strony wykorzystuje wyrzucanie elementów bezużytecznych i usuwanie obiektów, podobnie jak Java, do alokacji zmiennych. W rezultacie Go jest idealnym językiem do pracy w dowolnym systemie sprzętowym.
Niezrównana prostota Go
Jedną z głównych zalet przyjęcia Go jest jego prostota. Pomimo tego, że jest to bardzo wyrafinowany język z bogatym zestawem funkcji, Go wyróżnia się na tle innych ze względu na swoją prostotę i bezpośrednie podejście.
o Brak generyków: Generyki lub szablony, które od dawna stanowią podstawę różnych języków programowania, często zwiększają niejasność i trudności w zrozumieniu. Decydując się na rezygnację z tego, projektanci uprościli sprawę.
o Pojedynczy plik wykonywalny: GoLang nie zawiera biblioteki uruchomieniowej. Może wygenerować pojedynczy plik wykonywalny, który można wdrożyć po prostu kopiując. Zmniejsza to wszelkie obawy dotyczące popełniania błędów z powodu zależności lub niezgodności wersji.
o Brak bibliotek dynamicznych: Go zdecydowało się zrezygnować z bibliotek dynamicznych, aby zachować prostotę języka. Jednak w najnowszej wersji Go 1.10 programiści mogą przesyłać biblioteki dynamiczne za pośrednictwem pakietów wtyczek. Zostało to uwzględnione tylko jako dodatkowa funkcja.
Wbudowana struktura testowania i profilowania
Podczas tworzenia aplikacji JavaScript wielu z nas napotkało złożoność wyboru środowiska testowego poprzez serię analiz. Fakt, że przez większość czasu nie używamy więcej niż 20% wybranego frameworka, jest prawdą. Ten sam problem pojawia się, gdy do oceny wymagane jest dobre profilowanie. Go zawiera wbudowane narzędzie do testowania i profilowania, które pomaga nam szybko i łatwo przetestować aplikację. Oprócz dostarczania gotowych do wykonania przykładów kodu, narzędzie może być wykorzystywane do wszelkiego rodzaju potrzeb związanych z testowaniem i profilowaniem.
Łatwa krzywa uczenia się
Jedną z ważnych zalet Go jest niska krzywa uczenia się. Nie powinniśmy się dziwić, jeśli powiemy, że wszystkich funkcji GoLanga można się nauczyć w zaledwie kilka godzin. Kiedy opanujemy te podstawy, będziemy musieli zrozumieć najlepsze praktyki programistyczne dla określonych potrzeb, a także standardową bibliotekę. Jednak do nauki języka wystarczy dwu- lub trzygodzinna sesja.
POCZĄTEK OD GO
Kilka internetowych IDE, takich jak The Go Playground, repl.it i inne, może uruchamiać programy Go bez instalowania czegokolwiek. Aby zainstalować Go na naszych komputerach stacjonarnych lub laptopach, będziemy potrzebować dwóch programów: edytora tekstu i kompilatora.
Edytor tekstu
Edytor tekstu zapewnia nam platformę do pisania naszego kodu źródłowego. Poniżej znajduje się lista edytorów tekstu:
o Notatnik Windows
o Brief
o Polecenie edycji systemu operacyjnego
o Epsilon
o Kod VS
o vm lub vi
o Emacsa
Znalezienie kompilatora Go
Dystrybucja Go jest dostępna jako plik instalacyjny binarny dla systemów operacyjnych FreeBSD, Mac OS X, Linux i Windows z 32-bitowymi (386) i 64-bitowymi (amd64) architekturami procesorów x86.
ZAINSTALUJ Idź NA WINDOWS
Zanim zaczniemy, musimy najpierw zainstalować GoLang w naszym systemie. Potrzebujemy wiedzy z pierwszej ręki, czym jest język Go i do czego służy. Go to statycznie typowany język programowania typu open source, stworzony w 2007 roku przez Roberta Griesemera, Roba Pike'a i Kena Thompsona z Google, ale wydany w 2009 roku. Nosi również nazwę GoLang i obsługuje proceduralny język programowania. Początkowo został zaprojektowany w celu zwiększenia produktywności programowania na dużych bazach kodu, maszynach wielordzeniowych i sieciowych. Programy GoLang są łatwe do napisania. Można je napisać w dowolnym edytorze zwykłego tekstu, takim jak notatnik, notatnik ++ lub coś podobnego. Można również użyć internetowego IDE do napisania kodu GoLang lub zainstalować go w swoim systemie, aby ułatwić pisanie i pracę nad tymi kodami. Najlepsze jest to, że IDE ułatwia pisanie kodu GoLang, ponieważ IDE zawiera wiele funkcji, takich jak intuicyjny edytor kodu, debugger, kompilator itp. Po pierwsze, trzeba mieć zainstalowany język Go w swoim systemie, aby pisać kody GoLang i wykonywać różne intrygujące i wartościowe operacje.
Jak określamy wersję językową Go. To jest preinstalowane?
Zanim przystąpimy do instalacji Go, dobrze jest sprawdzić, czy nie jest ono już zainstalowane w naszym systemie. Aby sprawdzić, czy nasze urządzenie ma preinstalowany GoLang, przejdź do wiersza poleceń (dla Windows), wyszukaj cmd w oknie dialogowym Uruchom (+ R). Wykonaj następujące polecenie:
go version
Jeśli GoLang jest już zainstalowany na twoim komputerze, wygeneruje wiadomość zawierającą wszystkie szczegóły wersji GoLang; w przeciwnym razie, jeśli GoLang nie jest zainstalowany na komputerze, pojawi się komunikat o błędzie "Złe polecenie lub nazwa pliku".
Pobieranie i instalowanie Go
Zanim rozpoczniemy procedurę instalacji, musimy ją najpierw pobrać. Wszystkie wersje dla systemu Windows są dostępne do pobrania pod adresem https://go.dev/dl/.
Pobierz GoLang dla naszej architektury systemu, a następnie postępuj zgodnie z instrukcjami
Instrukcje instalacji GoLanga.
o Krok 1: Rozpakuj pobrany plik archiwum po jego pobraniu. Po rozpakowaniu znajdziemy folder go w naszym bieżącym katalogu.
o Krok 2: Skopiuj i wklej wyodrębniony folder, gdziekolwiek go umieścimy. W tym przypadku instalujemy go na dysku C.
o Krok 3: Teraz skonfiguruj zmienne środowiskowe. Kliknij prawym przyciskiem myszy Mój komputer i wybierz Właściwości. Wybierz Zaawansowane ustawienia systemu z lewego menu, a następnie Zmienne środowiskowe.
o Krok 4: Ze zmiennych systemowych wybierz Ścieżka, a następnie Edytuj. Następnie wybierz Nowy i wprowadź ścieżkę z katalogiem bin, do którego wkleiliśmy folder Go. Tutaj zmienimy ścieżkę C: gobiC: \ go \ bin i kliknij OK.
o Krok 5: Utwórz nową zmienną użytkownika, która powie poleceniu Go, gdzie znajdują się biblioteki GoLang. Aby to zrobić, przejdź do Zmiennych użytkownika i wybierz Nowy.
Teraz wprowadź GOROOT jako nazwę zmiennej i ścieżkę do naszego folderu GoLang jako wartość zmiennej. Tak więc w tym przypadku wartość zmiennej to C:\go\. Po zakończeniu wypełniania formularza kliknij OK.
Następnie w Zmiennych środowiskowych kliknij OK, a nasza konfiguracja jest zakończona. Teraz sprawdź wersję GoLang, wpisując wersję go w wierszu poleceń. Po zakończeniu procesu instalacji dowolny edytor tekstu lub IDE może użyć do napisania kodów GoLang, które następnie można uruchomić w IDE lub w wierszu polecenia za pomocą polecenia:
go run filename.go
PISANIE PIERWSZEGO PROGRAMU Go
package main
import "fmt"
func main() {
// print
fmt.Println("Hello, everyone")
}
Wyjaśnienie składni programu Go:
o Linia 1: zawiera główny pakiet programu, w tym jego całość treści. Jest to punkt wyjścia dla programu, więc musi być napisany.
o Linia 2: zawiera import "fmt", polecenie preprocesora, które instruuje kompilator, aby umieścił pliki w pakiecie.
o Linia 3: główna funkcja; to jest początek wykonywania programu.
o Linia 4: fmt.
o Println(): jest standardową funkcją biblioteczną służącą do drukowania czegoś na ekranie.
o Pakiet fmt: przesłał metodę Println, która w tym przypadku wyświetla wynik.
o Komentarze: służą do wyjaśniania kodu w taki sam sposób, jak w Javie, C lub C++. Wpisy komentarzy są ignorowane przez kompilatory i nie są wykonywane. Komentarze mogą mieć długość jednej lub wielu linii.
Komentarz jednowierszowy
Składnia:
// komentarz jednowierszowy
Komentarz wielowierszowy
Składnia:
/* komentarz wielowierszowy */
Przykład:
package main
import "fmt"
func main() {
fmt.Println("2 + 2 =", 2 + 2)
}
Wyjaśnienie poprzedniego programu
Poprzedni program używa tej samej linii pakietu, linii importu, deklaracji funkcji i funkcji Println, co pierwszy program Go. Zamiast wypisywać łańcuch "Cześć wszystkim", wypisujemy 2 + 2 =, po którym następuje wynik wyrażenia 2 + 2. To wyrażenie składa się z trzech części: literału liczbowego int 2, operatora + (reprezentującego dodawanie) i inny literał liczbowy typu int 2.
Dlaczego istnieje "język Go"?
Go jest próbą połączenia łatwości programowania języka interpretowanego i bezpieczeństwa języka statycznego i dynamicznego z wydajnością języka kompilowanego. Aspiruje również do tego, aby być najnowocześniejszym, z obsługą sieci i obliczeń wielordzeniowych.
Czego brakuje w Go, a jest w innych językach?
o Go stara się ograniczyć pisanie w obu znaczeniach tego słowa. Deweloperzy ciężko pracowali, aby ograniczyć bałagan i złożoność do minimum w całym procesie projektowania.
o Nie ma deklaracji przekazywania ani plików nagłówkowych; wszystko jest deklarowane tylko raz.
o Proste wyprowadzenie typu przy użyciu konstrukcji := zadeklaruj i zainicjuj zmniejsza zacinanie.reduces stuttering.
o Nie ma hierarchii typów: typy po prostu istnieją; nie są zobowiązani do ogłaszania swoich związków.
Ograniczenia sprzętowe
Zaobserwowaliśmy, że konfiguracja sprzętu i przetwarzania zmienia się w dłuższym tempie na przestrzeni dekady. W 2004 roku P4 miał taktowanie 3,0 GHz. W 2018 roku Macbook Pro miał taktowanie około (2,3 GHz vs. 2,66 GHz). Używamy większej liczby procesorów, aby przyspieszyć działanie, ale koszt korzystania z większej liczby procesorów również rośnie. W rezultacie używamy ograniczonych procesorów, a przy niewielkiej liczbie procesorów mamy ciężki język programowania, którego wątkowanie zużywa więcej pamięci i spowalnia wydajność naszego systemu. Aby rozwiązać ten problem, GoLang został zaprojektowany w taki sposób, że zamiast wątkowania używa gorutyny, która jest podobna do wątkowania, ale zużywa znacznie mniej pamięci. Ponieważ wątki zużywają 1 MB pamięci, a goroutines 2 KB, łatwo jest uruchomić miliony goroutines jednocześnie. W wyniku powyższych punktów GoLang jest potężnym językiem, który obsługuje współbieżność w taki sam sposób, jak robią to C++ i Java.
Zalety i wady języka Go
Korzyści:
o Elastyczny: jest elastyczny, ponieważ jest zwięzły, prosty i łatwy do odczytania.
o Współbieżność: umożliwia jednoczesne uruchamianie wielu procesów i efektywnie.
o Szybka kompilacja: Czas kompilacji jest bardzo krótki.
o Biblioteka: zawiera obszerną bibliotekę standardową.
o Wyrzucanie śmieci to podstawowa funkcja go. Go wyróżnia się zapewnianiem wysokiego poziomu kontroli nad alokacją pamięci, a opóźnienie modułu wyrzucania elementów bezużytecznych zostało radykalnie zmniejszone w ostatnich wersjach.
o Sprawdza osadzanie interfejsu i typu.
Wady:
o Mimo wielu dyskusji na ten temat, nie obsługuje leków generycznych.
o Chociaż pakiety dołączone do tego języka programowania są bardzo pomocne, Go nie jest obiektowym językiem programowania w tradycyjnym tego słowa znaczeniu.
o Brakuje niektórych bibliotek, zwłaszcza zestawu narzędzi interfejsu użytkownika.
Niektóre popularne aplikacje języka Go obejmują:
o Docker: Jest to zestaw narzędzi do zarządzania i wdrażania kontenerów Linuksa.
o Red Hat: jest Openshift i jest platformą przetwarzania w chmurze jako usługą.
o Kubernetes: Przyszłość płynnie zautomatyzowanego wdrażania.
o Dropbox: przeniósł niektóre ze swoich krytycznych komponentów z Pythona do Go.
o Netflix: Dla dwóch różnych aspektów ich architektury serwerowej.
o InfluxDB: Jest to baza danych szeregów czasowych, która jest open source i została opracowana przez InfluxData.
o GoLang: język został stworzony w Go.
TERMINAL
GoLand posiada zintegrowany emulator terminala, który pozwala nam na interakcję z naszą powłoką wiersza poleceń z poziomu IDE. Może uruchamiać polecenia Git, modyfikować uprawnienia do plików i wykonywać inne funkcje wiersza poleceń bez przełączania się do specjalistycznego programu terminala. Emulator terminala zaczyna się od naszej normalnej powłoki systemowej, ale obsługuje wiele alternatywnych powłok, w tym Windows PowerShell, Command Prompt cmd.exe, sh, bash, zsh, csh i inne. Zobacz Konfigurowanie emulatora terminala, aby uzyskać więcej informacji na temat zmiany powłoki.
Otwórz okno narzędzia Terminal
Wybierz Widok | Okna narzędziowe | Terminal z menu głównego lub naciśnij Alt+F12. Domyślnie emulator terminala działa z bieżącym katalogiem ustawionym na katalog główny bieżącego projektu. Alternatywnie możemy kliknąć prawym przyciskiem myszy dowolny plik (na przykład w oknie narzędzia Projekt lub dowolnej otwartej karcie) i wybrać Otwórz w terminalu z menu kontekstowego, aby uruchomić okno narzędzia Terminal z nową sesją w katalogu pliku.
Rozpocznij nową sesję
Kliknij przycisk Dodaj, aby utworzyć nową sesję w nowej zakładce na pasku narzędzi. Aby uruchomić kilka sesji na karcie, kliknij ją prawym przyciskiem myszy i wybierz z menu kontekstowego opcję Podziel w prawo lub Podziel w dół. Kiedy zamykamy projekt lub GoLand, Terminal zapamiętuje zakładki i sesje. Nazwy kart, historia powłoki i bieżący katalog roboczy są zapisywane. Użyj przycisku Zamknij na pasku narzędzi Terminala lub kliknij kartę prawym przyciskiem myszy i wybierz opcję Zamknij kartę z menu kontekstowego, aby zamknąć kartę. Aby przechodzić między aktywnymi kartami, naciśnij klawisze Alt+w prawo i Alt+w lewo. Możemy również nacisnąć Alt + Down, aby uzyskać listę wszystkich kart terminala. Kliknij kartę prawym przyciskiem myszy i wybierz opcję Zmień nazwę sesji z menu kontekstowego, aby zmienić jej nazwę. Ctrl + F wyszuka określony ciąg w sesji terminala. Spowoduje to przeszukanie całego tekstu sesji, w tym monitu, poleceń i danych wyjściowych. Skonfiguruj emulator terminala w następujący sposób:
Aby otworzyć ustawienia środowiska IDE, naciśnij klawisze Ctrl+Alt+S, a następnie wybierz pozycję Narzędzia | Terminal.
ZAINSTALUJ G NA MAC
Zanim zaczniemy, musimy najpierw zainstalować GoLang w naszym systemie. Potrzebujemy wiedzy z pierwszej ręki, czym jest język Go i do czego służy. Go to statycznie typowany język programowania typu open source, stworzony w 2007 roku przez Roberta Griesemera, Roba Pike'a i Kena Thompsona z Google, ale wydany w 2009 roku. Nosi również nazwę GoLang i obsługuje proceduralny język programowania. Pierwotnie został zaprojektowany w celu zwiększenia produktywności programowania na dużych bazach kodu, maszynach wielordzeniowych i sieciowych. Programy GoLang można tworzyć w dowolnym edytorze zwykłego tekstu, takim jak TextEdit, Sublime Text lub podobnym. Można również użyć internetowego IDE do napisania kodu GoLang lub zainstalować go w swoim systemie, aby ułatwić pisanie i pracę nad tymi kodami. Dla wygody użycie IDE ułatwia pisanie kodu GoLang, ponieważ IDE zawiera wiele funkcji, takich jak intuicyjny edytor kodu, debugger, kompilator itp. Poniżej przedstawiono kroki instalacji GoLang na MacOS:
o Krok 1: Określ, czy aplikacja Go jest zainstalowana. Zanim zaczniemy instalować Go, dobrze jest sprawdzić, czy nie jest już zainstalowane w naszym systemie. Aby sprawdzić, czy nasze urządzenie ma preinstalowany GoLang, otwórz Terminal i wpisz następujące polecenie:
go version
Jeśli GoLang jest już zainstalowany na twoim komputerze, wygeneruje wiadomość ze wszystkimi dostępnymi szczegółami wersji GoLang; w przeciwnym razie wyświetli błąd.
o Krok 2: Zanim rozpoczniemy proces instalacji, musimy go najpierw pobrać. W rezultacie wszystkie wersje Go dla MacOS są dostępne do pobrania pod adresem https://go.dev/dl/. Pobierz GoLang w oparciu o naszą architekturę systemu. Dla systemu pobraliśmy go1.13.1drawin-amd64.pkg.
o Krok 3: Po pobraniu pakietu zainstaluj go w naszym systemie.
o Krok 4: Po zakończeniu procesów instalacyjnych. Otwórz Terminal (interfejs wiersza poleceń dla systemu MacOS) i użyj polecenia wersji GoLang, aby sprawdzić, czy Go jest poprawnie zainstalowany. Wyświetla informacje o wersji GoLang, wskazując, że Go został pomyślnie zainstalowany w naszym systemie.
Po pomyślnym zainstalowaniu Go w naszym systemie skonfigurujemy teraz obszar roboczy Go. Obszar roboczy Go to folder na naszym komputerze, w którym będzie przechowywany cały nasz kod Go.
o Krok 1: Utwórz folder o nazwie Go w naszych dokumentach (lub gdziekolwiek chcemy w naszym systemie).
o Krok 2: Powiedz narzędziom Go, gdzie mają szukać tego folderu. Aby rozpocząć, użyj następującego polecenia, aby przejść do naszego katalogu domowego:
cd ~
Następnie użyj następującego polecenia, aby ustawić ścieżkę do folderu:
echo "export GOPATH=/Users/anki/Documents/go" >> .bash_profile
W tym przypadku dodajemy export OPATH=/Users/anki/Documents/go do .bash_profile. Plik profilu .bash jest ładowany automatycznie, gdy logujemy się na nasze konto Mac i zawiera wszystkie konfiguracje i preferencje uruchamiania interfejsu wiersza poleceń (CLI).
o Krok 3: Uruchom następujące polecenie, aby upewnić się, że nasz plik .bash_profile zawiera następującą ścieżkę:
cat. bash_profile
o Krok 4: Teraz użyjemy następującego polecenia, aby zweryfikować naszą ścieżkę go. Możemy również pominąć ten krok, jeśli wolimy.
echo $GOPATH
Tworzenie naszego pierwszego programu
o Krok 1: Pobierz, a następnie zainstaluj wybrany edytor tekstu. Utwórz folder w Dokumentach o nazwie Go (lub dowolną nazwę) po instalacji (lub gdziekolwiek chcemy w naszym systemie). Utwórz inny folder o nazwie źródło w tym folderze i inny folder o nazwie powitanie w tym folderze źródłowym. Wszystkie nasze programy w Go będą zapisywane w tym folderze.
o Krok 2: Napiszmy nasz pierwszy program w Go. Otwórz edytor tekstu i wpisz program Go.
o Krok 3: Po utworzeniu programu Go zapisz go z rozszerzeniem .go.
o Krok 4: Uruchom terminal, aby wykonać swój pierwszy program Go.
o Krok 5: Zmień lokalizację plików naszego programu.
o Krok 6: Po zmianie katalogów użyj następującego polecenia, aby uruchomić program Go:
go run name_of_the_program.go
Wykonaj program Go
Przyjrzyjmy się, jak zapisać kod źródłowy w pliku, skompilować go, a następnie uruchomić program. Postępuj zgodnie z poniższymi instrukcjami:
o Otwórz edytor tekstu i wklej do niego powyższy kod.
o Zapisz plik pod nazwą helloo.go
o Otwórz wiersz polecenia.
o Przejdź do lokalizacji zapisanego pliku.
o Wpisz go run hello.
o Aby uruchomić nasz kod, śmiało naciśnij enter.
o Jeśli twój kod jest wolny od błędów, na ekranie zobaczymy napis "Cześć wszystkim".
$ go run helloo.go
Witam wszystkich
Upewnij się, że kompilator Go znajduje się na naszej ścieżce i że działa w katalogu zawierającym plik źródłowy helloo.go. Czy programy w Go łączą się z językiem programowania C/C++? Rzeczywiście możliwe jest użycie C i Go w tej samej przestrzeni adresowej, ale nie jest to naturalne dopasowanie i może wymagać użycia specjalnego oprogramowania interfejsu. Ponadto łączenie kodu C z kodem Go poświęca bezpieczeństwo pamięci Go i właściwości zarządzania stosem. Czasami użycie bibliotek C do rozwiązania problemu jest konieczne, ale robienie tego zawsze wprowadza element ryzyka, którego nie ma w czystym kodzie Go, więc postępuj ostrożnie. Jeśli musimy używać C z Go, sposób postępowania zależy od implementacji kompilatora Go. Zespół Go zapewnia wsparcie dla trzech implementacji kompilatora Go. Domyślnym kompilatorem jest GC, a następnie gccgo, który korzysta z zaplecza GCC, oraz nieco mniej dojrzały gollvm, który wykorzystuje infrastrukturę LLVM. Ponieważ gc ma inną konwencję wywoływania i linker niż C, nie można go wywołać bezpośrednio z programów C i odwrotnie. Program cgo implementuje "interfejs funkcji obcych", który umożliwia kodowi Go bezpieczne wywoływanie bibliotek C. Ta możliwość została rozszerzona na biblioteki C++ przez firmę SWIG. Gccgo i gollvm mogą być również używane z cgo i SWIG. Ponieważ używają tradycyjnego interfejsu API, możliwe jest łączenie kodu z tych kompilatorów bezpośrednio z programami C lub C++ skompilowanymi przez GCC/LLVM z zachowaniem ostrożności. Jednak wykonanie tego w bezpieczny sposób wymaga znajomości konwencji wywoływania we wszystkich językach i rozważenia ograniczeń stosu podczas wywoływania C lub C++ z Go.
JAK W GoLang TWORZYMY PUSTY PLIK?
Go Language, podobnie jak inne języki komputerowe, pozwala nam konstruować pliki. Oferuje funkcję Create() do tworzenia pliku, która służy do tworzenia lub obcinania podanego nazwanego pliku. Jeśli określony plik już istnieje, ta metoda go obetnie. Jeśli określony plik nie istnieje, ta metoda utworzy go w trybie 0666. Ta procedura zwróci wyjątek *PathError, jeśli określona ścieżka jest niepoprawna. Ta funkcja zwraca deskryptor pliku, który może być odczytywany i zapisywany. Ponieważ jest to określone w pakiecie os, musimy zaimportować pakiet os do naszego programu, aby użyć metody Create().
Składnia:
func Create(file-name string) (*File, error)
Pierwszy przykład:
package main
import (
"log"
"os"
)
func main() {
// empty file Creation
// Create() function Using
myfile, es := os.Create("helloo.txt")
if es != nil {
log.Fatal(es)
}
log.Println(myfile)
myfile.Close()
}
Drugi przykład:
package main
import (
"log"
"os"
)
func main() {
// empty file Creation
// Create() function Using
myfile, es := os.Create("/Users/anki/
Documents/new_folder/helloo.txt")
if es != nil {
log.Fatal(es)
}
log.Println(myfile)
myfile.Close()
}
W GoLang możemy sprawdzić, czy dany plik istnieje, czy nie. Funkcja IsNotExist() w języku programowania Go pozwala nam określić, czy dany plik istnieje, czy nie. Jeśli powyższa funkcja zwróci wartość true, wówczas znany jest błąd informujący, że określony plik lub katalog już nie istnieje, a jeśli zwróci wartość false, oznacza to, że podany plik lub katalog istnieje. ErrNotExist i kilka błędów wywołań systemowych również spełnia wymagania tej procedury. Ponieważ jest to określone w pakiecie os, musimy zaimportować pakiet os do naszego programu, aby użyć metody IsNotExist() .
Składnia:
func IsNotExist(es error) bool
Pierwszy przykład:
package main
import (
"log"
"os"
)
var (
myfile *os.FileInfo
es error
)
func main() {
// Stat() function returns the file info and
//if there is no file, then it will return
error
myfile, es := os.Stat("helloo.txt")
if es != nil {
// Checking if given file exists or not
// Using the IsNotExist() function
if os.IsNotExist(es) {
log.Fatal("File not Found")
}
}
log.Println("File Exist")
log.Println("File Detail is:")
log.Println("Name is: ", myfile.Name())
log.Println("Size is: ", myfile.Size())
}
Drugi przykład:
package main
import (
"log"
"os"
)
var (
myfile *os.FileInfo
es error
)
func main() {
// Stat() function returns the file info and
// if there is no file, then it will return
error
myfile, es := os.Stat("/Users/anki/Documents/
new_folder/myfolder/helloo.txt")
if es != nil {
// Checking if given file exists or not
// Using IsNotExist() function
if os.IsNotExist(es) {
log.Fatal("File not Found")
}
}
log.Println("File Exist")
log.Println("File Detail is:")
log.Println("Name is: ", myfile.Name())
log.Println("Size is: ", myfile.Size())
}
UTWÓRZ KATALOG W Go
W Go użyj metody os.Mkdir(), aby utworzyć pojedynczy katalog. Użyj os.MkdirAll() do ustanowienia hierarchii folderów (katalogi zagnieżdżone). Obie metody wymagają ścieżki i bitów uprawnień do folderu jako parametrów.
Utwórz pojedynczy katalog
package main
import (
"log"
"os"
)
func main() {
if er := os.Mkdir("a", os.ModePerm); er != nil {
log.Fatal(er)
}
}
Make a Directory Hierarchy (Nested Directories)
package main
import (
"log"
"os"
)
func main() {
if er := os.MkdirAll("a/b/c/d", os.ModePerm); er
!= nil {
log.Fatal(er)
}
}
Funkcja os.Mkdir() generuje nowy katalog o podanej wartości name, ale nie pozwala na tworzenie podkatalogów. W tym rozdziale omówiliśmy wprowadzenie Go z jego funkcjami, zaletami i wadami. Omówiliśmy również instalację Go w systemach Windows i Mac. Ponadto omówiliśmy pliki i foldery, terminal i edytory tekstu
Narzędzia GoLang
JAK CZYTAĆ I PISAĆ PROGRAMY W Go
GoLang zawiera obszerną wbudowaną bibliotekę, której można używać do przeprowadzania operacji odczytu i zapisu plików. Moduł io/ioutil polega na czytaniu z plików w systemie lokalnym. Można użyć modułu io/ioutil do zapisania danych do pliku. Moduł fmt obsługuje sformatowane wejścia/wyjścia, udostępniając metody odczytu danych wejściowych ze standardowego wejścia i drukowania danych wyjściowych na standardowe wyjście. Moduł log to podstawowy pakiet rejestrowania, który jest zaimplementowany. Wprowadza typ Logger z metodami formatowania danych wyjściowych. Moduł os pozwala nam korzystać z natywnych funkcji systemu operacyjnego. Buforowane wejścia/wyjścia są realizowane przez moduł bufio, co pomaga zwiększyć szybkość procesora.
o os.Create(): Ta funkcja tworzy plik o określonej nazwie. Jeśli istnieje już inny plik o tej samej nazwie, metoda create go obcina.
o ioutil.ReadFile(): Jedynym parametrem funkcji ioutil.ReadFile() jest ścieżka do pliku, który ma zostać odczytany. Ta procedura zwraca zawartość pliku lub błąd.
o ioutil.WriteFile(): Zwraca ioutil. WriteFile() to funkcja służąca do zapisywania danych do pliku. Funkcja WriteFile() przyjmuje trzy parametry: lokalizację pliku, do którego chcemy pisać, obiekt danych oraz FileMode, który zawiera tryb i uprawnienia pliku bits.log.
o Fatalf: Fatalf zakończy działanie aplikacji po wydrukowaniu komunikatu dziennika. Jest to podobne do wykonywania funkcji Printf(), a następnie os.Exit (1).
o log.Panicf: Panika jest podobna do wyjątku, który może wystąpić w czasie wykonywania. Panicln jest tym samym co Println(), po którym następuje wywołanie panic(). Parametr przekazany do panic() jest wyświetlany po zamknięciu programu.
o bufio.NewReader(os.Stdin): Ta funkcja zwraca nowy czytnik z domyślnym rozmiarem bufora (4096 bajtów).
o inputReader.ReadString('n'): Ta metoda odczytuje dane wprowadzone przez użytkownika ze standardowego wejścia do pierwszego wystąpienia separatora na wejściu i zwraca ciąg znaków zawierający dane do separatora włącznie. Błąd przed zlokalizowaniem ogranicznika zawiera dane odczytane przed błędem i sam błąd.
Pierwszy przykład: aby uzyskać najlepsze wyniki, użyj kompilatora offline. Zapisz plik jako plik .go. Aby uruchomić program, wykonaj poniższe polecenie.
go run file-name.go
// program to read and write files
package main
// importing packages
import (
"fmt"
"io/ioutil"
"log"
"os"
)
func CreateFile() {
// fmt package implements formatted I/O, it
has functions like Printf and Scanf
fmt.Printf("Writing file in Go lang\n")
// in case error is thrown it is received by
err variable and Fatalf method of
// log prints error message and stops program
execution
file, er := os.Create("test1.txt")
if er != nil {
log.Fatalf("failed creating file: %s", er)
}
// Defer is used for the purposes of cleanup
like closing a running file after the file has
// been written and the main function has
completed execution
defer file.Close()
// len variable captures the length of string
written to the file.
len, er := file.WriteString("Welcome
Everyone"+
" Program demonstrates reading and
writing"+
" operations to a file in
the Go lang.")
if er != nil {
log.Fatalf("failed writing to file: %s", er)
}
// Name() method returns name of the file as
presented to Create() method.
fmt.Printf("\nFile Name: %s", file.Name())
fmt.Printf("\nLength: %d bytes", len)
}
func ReadFile() {
fmt.Printf("\n\nReading a file in the Go
lang\n")
fileName := "test1.txt"
// The ioutil package contains inbuilt
// methods like ReadFile that reads
// filename and returns contents.
data, er := ioutil.ReadFile("test.txt")
if er != nil {
log.Panicf("failed reading data from file:
%s", er)
}
fmt.Printf("\nFile Name is: %s", fileName)
fmt.Printf("\nSize is: %d bytes", len(data))
fmt.Printf("\nData is: %s", data)
}
// main function
func main() {
CreateFile()
ReadFile()
}
Drugi przykład: kod programu GoLang odczytuje i zapisuje pliki na podstawie danych wprowadzonych przez użytkownika.
// Program to read and write files
package main
// importing requires packages
import (
"bufio"
"fmt"
"io/ioutil"
"log"
"os"
)
func CreateFile(filename, text string)
{
// fmt package implements formatted I/O
// and contains the inbuilt methods like the
Printf and Scanf
fmt.Printf("Writing to a file in the Go
lang\n")
// Creating file using Create() method with
user inputted filename and err
// variable catches any error thrown
file, er := os.Create(filename)
if er != nil {
log.Fatalf("failed creating file: %s", er)
}
// closing running file after the main method
has completed execution and
// writing to the file is complete
defer file.Close()
// writing data to file using
// WriteString() method and
// length of the string is stored in the len
variable
len, er := file.WriteString(text)
if er != nil {
log.Fatalf("failed writing to file: %s",
er)
}
fmt.Printf("\nFile Name is: %s", file.Name())
fmt.Printf("\nLength is: %d bytes", len)
}
func ReadFile(filename string) {
fmt.Printf("\n\nReading a file in the Go
lang\n")
// file is read using ReadFile() method of the
ioutil package
data, err := ioutil.ReadFile(filename)
// in case of an error
// the error statement is printed, program is
stopped
if er != nil {
log.Panicf("failed reading data from file:
%s", er)
}
fmt.Printf("\nFile Name is: %s", filename)
fmt.Printf("\nSize is: %d bytes", len(data))
fmt.Printf("\nData is: %s", data)
}
// main function
func main() {
// user input for the filename
fmt.Println("Enter-filename: ")
var filename string
fmt.Scanln(&filename)
// user input for the file content
fmt.Println("Enter-text: ")
inputReader := bufio.NewReader(os.Stdin)
input, _ := inputReader.ReadString('\n')
// file is created then read
CreateFile(filename, input)
ReadFile(filename)
}
W GoLang, JAK ZMIENIĆ NAZWĘ I PRZENIEŚĆ PLIK
Funkcja Rename() w języku programowania Go pozwala nam zmienić nazwę i przenieść istniejący plik do nowego katalogu. Ta procedura służy do zmiany nazwy i przesyłania pliku z jednej ścieżki do drugiej. Jeśli określona nowa ścieżka już istnieje i nie znajduje się w katalogu, ta procedura ją zastąpi. Mogą jednak obowiązywać ograniczenia specyficzne dla systemu operacyjnego, jeśli określone stare i nowe ścieżki znajdują się w oddzielnych katalogach. Jeśli określona ścieżka jest błędna, wpisanie *LinkError spowoduje zgłoszenie błędu. Ponieważ jest to określone w pakiecie os, musimy zaimportować pakiet os do naszego programu, aby użyć metody Remove().
Składnia:
func Rename(old-path, new-path string) error
Pierwszy przykład:
// Program to illustrate how to rename,
// move a file in the default directory
package main
import (
"log"
"os"
)
func main() {
// Rename and Remove a file
// Using Rename() function
OriginalPath := "helloo.txt"
NewPath := "abc.txt"
es := os.Rename(Original_Path, New_Path)
if es != nil {
log.Fatal(es)
}
}
Drugi przykład:
// Program to illustrate how to rename,
//remove a file in new directory
package main
import (
"log"
"os"
)
func main() {
// Rename and Remove file
// Using Rename() function
OriginalPath := "/Users/anki/Documents/new_
folder/helloo.txt"
NewPath := "/Users/anki/Documents/new_folder/
myfolder/abc.txt"
es := os.Rename(OriginalPath, NewPath)
if es != nil {
log.Fatal(es)
}
}
JAK CZYTAĆ PLIKI LINIA PO LINII DO STRINGU
Pakiet bufio Scanner służy do odczytu pliku linia po linii. Niech plik tekstowy będzie się nazywał sample1.txt, a zawartość pliku będzie następująca. Język programowania Go to statycznie kompilowany język programowania typu open source. Rob Pike, Ken Thompson i Robert Grieserner stworzyli go w Google. Czasami jest określany jako GoLang. Język programowania Go to język programowania ogólnego przeznaczenia przeznaczony do tworzenia skomplikowanego oprogramowania na dużą skalę.
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
// os.Open() opens specific file in the
// read-only mode,
// this return pointer of type os.
file, er := os.Open("sample1.txt")
if er != nil {
log.Fatalf("failed to open")
}
// bufio.NewScanner() function is called in which
// object os.File passed as its parameter
// this returns object bufio.Scanner which is used
on the
// bufio.Scanner.Split() method
scanner := bufio.NewScanner(file)
// The bufio.ScanLines is used as
// input to method bufio.Scanner.Split()
// and then scanning forwards to each
// new line using bufio.Scanner.Scan() method.
scanner.Split(bufio.ScanLines)
var text []string
for scanner.Scan() {
text = append(text, scanner.Text())
}
// The method os.File.Close() is called
// on the os.File object to close filev
file.Close()
// and then a loop iterates through,
// prints each of the slice values.
for _, each_ln := range text {
fmt.Println(each_ln)
}
}
Typy danych
Omówiliśmy, jak odczytać plik w Go i jak zmienić jego nazwę. Tu będziemy zawijać liczby, wartości logiczne i ciągi znaków.
PODSTAWOWA SKŁADNIA
Przyjrzeliśmy się podstawowej strukturze programu Go. Inne istotne części składowe języka programowania Go będą teraz znacznie łatwiejsze do zrozumienia.
Tokeny
Program Go składa się z różnych tokenów. Tokenami mogą być słowa kluczowe, identyfikatory, stałe, literały łańcuchowe lub symbole. Na przykład poniższa instrukcja Go składa się z sześciu tokenów:
fmt.Println("Witam wszystkich")
Poszczególne tokeny są następujące:
fmt
.
Println
(
"Witam wszystkich"
)
Separator linii
Klawisz separatora linii jest terminatorem instrukcji w programie Go. Innymi słowy, poszczególne instrukcje nie wymagają szczególnego separatora, takiego jak ";" w C. Kompilator Go używa terminatora instrukcji ";" aby oznaczać koniec jednej logicznej jednostki. Spójrz na przykład na następujące instrukcje:
fmt.Println("Hello, Everyone")
fmt.Println("We are in the world of Go Programming")
Kometarze
Komentarze są podobne do komunikatów pomocy w naszym programie Go, a kompilator je ignoruje. Zaczynają się od/* i kończą znakami */, jak pokazano poniżej.
/* Mój pierwszy program w Go */
W komentarzach nie może być żadnych komentarzy i nie pojawiają się one w ciągach ani literałach znaków.
Identyfikatory
Identyfikator Go identyfikuje zmienną, funkcję lub inną jednostkę zdefiniowaną przez użytkownika. Identyfikator zaczyna się od litery od A do Z, od a do z lub podkreślenia. Po nim mogą występować podkreślenia, zero lub więcej liter lub cyfr.
identyfikator = litera { litera | cyfra_unicode }
Znaki interpunkcyjne, takie jak @, $ i procent, nie są dozwolone w identyfikatorach w Go. Go to język komputerowy, w którym rozróżniana jest wielkość liter. Tak więc w Go Siła Robocza i siła robocza to dwie odrębne tożsamości. Oto kilka przykładów odpowiednich identyfikatorów:
ramesh sehgal xyz move_name x_123
myname40 _temp j x23b8 retVal
Słowa kluczowe nie mogą być używane jako identyfikatory. Identyfikator _ to unikalny identyfikator, czasami nazywany pustym identyfikatorem. Później odkryjemy, że wszystkie typy, zmienne, stałe, etykiety, nazwy pakietów i nazwy importu pakietów muszą być identyfikatorami. Wyeksportowany identyfikator zaczyna się od wielkiej litery Unicode. W wielu innych językach słowo wyeksportowane można przetłumaczyć jako publiczne. Nieeksportowane identyfikatory nie zaczynają się od wielkiej litery Unicode. Określenie "nieeksportowane" można rozumieć jako "prywatne w kilku różnych językach". Znaki wschodnie są teraz klasyfikowane jako litery nieeksportowane. Niewyeksportowane identyfikatory są czasami nazywane niewyeksportowanymi identyfikatorami. Oto kilka przykładów legalnie wyeksportowanych identyfikatorów:
Gracz_7
Zrobił coś
WERSJA
?
Oto kilka przykładów legalnych, niewyeksportowanych identyfikatorów:
_
_status
memeStat
books
?
Oto kilka przykładów tokenów, których nie wolno używać jako identyfikatory:
// Począwszy od cyfry Unicode.
321
4 jabłka
// Zawierające znaki Unicode nie
// spełnianie wymagań.
c.d
*ptr
$names
c@d.e
// To są słowa kluczowe.
type
range
Słowa kluczowe
Terminy zastrzeżone w Go są wymienione w poniższej tabeli. Te zastrzeżone terminy nie mogą być używane jako stałe, zmienne lub inne identyfikatory.
case default import interface struct
chan defer go map select
break else if package type
const fallthrough goto range switch
continue for func return var
Są one podzielone na sześć kategorii: const, func, import, package, type i var służą do deklarowania różnych typów komponentów kodu w programach Go. Niektóre denotacje typu złożonego używają chan, interface, map i struct jako składników. Aby zarządzać przepływem kodu, używane są break, case, continue, default, other, fallthrough, for, goto, if, range, return, select i switch. Zarówno defer, jak i go kontrolują warunki przepływu, chociaż na różne sposoby.
Biała przestrzeń
W Go białe znaki odnoszą się do spacji, tabulacji, znaków nowej linii i komentarzy. Pusta linia ma po prostu białe znaki, być może z uwagą, i jest całkowicie ignorowana przez kompilator Go. Białe znaki oddzielają jedną sekcję instrukcji od drugiej i pozwalają kompilatorowi określić, gdzie kończy się jeden element, int, a zaczyna następny element w instrukcji. W rezultacie w poniższej instrukcji
var ages int;
Aby kompilator mógł rozróżnić int i age, musi istnieć co najmniej jeden biały znak (zwykle spacja). Dla kontrastu rozważmy następujące stwierdzenie:
fruits = grapes + oranges; // pobierz całkowitą ilość owoców
Nie ma spacji wymaganych między owocami a = lub między = a grapes; jednak mile widziane jest uwzględnienie każdego ze względu na czytelność.
TYPY DANYCH W Go
Typy danych definiują rodzaje danych przechowywanych w poprawnej zmiennej Go. Typ jest podzielony na cztery typy w języku Go, które są następujące:
o Liczby, łańcuchy i wartości logiczne to przykłady typów podstawowych.
o Tablice i struktury to przykłady typów agregatów.
o Wskaźniki, wycinki, mapy, funkcje i kanały to przykłady typów odwołań.
o Typ interfejsu.
W tej sekcji omówimy podstawowe typy danych w języku programowania Go. Podstawowe typy danych są dalej podzielone na trzy podkategorie, które są następujące:
o Liczby
o Logiczne
o Struny
Liczby
Liczby w Go są podzielone na trzy podkategorie, które są następujące:
o Liczby całkowite: Język Go obsługuje zarówno liczby całkowite ze znakiem, jak i bez znaku w czterech różnych rozmiarach, jak pokazano w poniższej tabeli. Liczba całkowita ze znakiem jest oznaczona przez int, podczas gdy liczba całkowita bez znaku jest oznaczona przez uint.
Typ: Opis
int8 : 8-bitowa liczba całkowita ze znakiem
int16 : 16-bitowa liczba całkowita ze znakiem
int32 : 32-bitowa liczba całkowita ze znakiem
int64 : 64-bitowa liczba całkowita ze znakiem
uint8 : 8-bitowa liczba całkowita bez znaku
uint16: 16-bitowa liczba całkowita bez znaku
uint32: 32-bitowa liczba całkowita bez znaku
uint64: 64-bitowa liczba całkowita bez znaku
Int : In i uint mają ten sam rozmiar, 32 lub 64 bity
uint : In i uint mają ten sam rozmiar, 32 lub 64 bity
Rune : Jest taki sam jak int32 i reprezentuje punkty kodowe Unicode
Bajt: Jest to skrót od uint8
Uintptr : Jest to typ liczby całkowitej bez znaku. Nie ma stałej szerokości, ale może przechowywać wszystkie bity wartości wskaźnika
Przykład :
package main
import "fmt"
func main() {
// 8-bit unsigned int usingv
var A uint8 = 225
fmt.Println(A, A-3)
// Using 16-bit signed int
var B int16 = 32767
fmt.Println(B+2, B-2)
}
Liczby zmiennoprzecinkowe
W Go liczby zmiennoprzecinkowe dzielą się na dwa typy, co ilustruje poniższa tabela:
Typ danych: opis
float32 : 32-bitowa liczba zmiennoprzecinkowa IEEE 754
float64 : 64-bitowa liczba zmiennoprzecinkowa IEEE 754
Przykład:
package main
import "fmt"
func main()
{
x := 22.46
y := 35.88
// Subtract of two floating-point number
z := y-x
// Display result
fmt.Printf("Result is: %f", z)
// Display type of c variable
fmt.Printf("\nThe type of z is : %T", z)
}
Liczby zespolone
Liczby zespolone są podzielone na dwie części w poniższej tabeli. Te złożone liczby całkowite obejmują również liczbę zmiennoprzecinkową32 i zmiennoprzecinkową64. Wbudowana funkcja generuje liczbę zespoloną ze swoich składników urojonych i rzeczywistych, podczas gdy wbudowane funkcje urojone i rzeczywiste usuwają te składniki.
Typ danych: opis
complex64 : Liczby zespolone z float32 jako składnikiem rzeczywistym i urojonym.
complex128 : Liczby zespolone z float64 jako składową rzeczywistą i urojoną.
Przykład:
package main
import "fmt"
func main() {
var x complex128 = complex(7, 3)
var y complex64 = complex(8, 3)
fmt.Println(x)
fmt.Println(y)
// Display type
fmt.Printf("The type of x is %T and "+
"the type of y is %T", x, y)
}
Logiczne
Typ danych Boolean reprezentuje tylko jeden bit informacji: prawda lub fałsz. Wartości typu Boolean nie są z natury ani jawnie przekształcane na żaden inny typ.
Przykład :
package main
import "fmt"
func main() {
// variables
strg1 := "PeeksofPeeks"
strg2:= "peeksofpeeks"
strg3:= "PeeksofPeeks"
results1:= strg1 == strg2
results2:= strg1 == strg3
// Display result
fmt.Println( results1)
fmt.Println( results2)
// Display type of
// results1 and results2
fmt.Printf("The type of results1 is %T and "+
"the type of results2 is %T",
results1, results2)
}
Stringi
Typ danych łańcuchowych to seria punktów kodowych Unicode. Innymi słowy, ciąg to seria niezmiennych bajtów, co oznacza, że raz utworzony ciąg nie może się zmienić. Ciąg może zawierać dowolne dane w formie czytelnej dla człowieka, w tym bajty o wartości zerowej.
Przykład:
package main
import "fmt"
func main()
{
// strf variable stores strings
strg := "PeeksofPeeks"
// Display length of the string
fmt.Printf("Length of the string is:%d",
len(strg))
// Display string
fmt.Printf("\nString is: %s", strg)
// Display type of strg variable
fmt.Printf("\nType of strg is: %T", strg)
}
Zmienne i stałe
ZMIENNE W Go
Typowy program wykorzystuje wiele zmiennych, które mogą zmieniać się podczas wykonywania. Rozważmy na przykład program, który wykonuje różne operacje na wartościach wprowadzonych przez użytkownika. Wartości przesłane przez jednego użytkownika mogą różnić się od wartości wprowadzonych przez innego. W rezultacie wymagane są zmienne. Dzieje się tak dlatego, że inny użytkownik może nie wykorzystać ponownie tych samych wartości. Kiedy użytkownik wprowadzi nową wartość w procesie operacji, która będzie dalej wykorzystywana, może przechowywać ją tymczasowo w pamięci o dostępie swobodnym komputera, a wartości w tym obszarze pamięci zmieniają się w trakcie wykonywania, dając na to inne określenie, który jest znany jako zmienne. Tak więc w istocie zmienna jest symbolem zastępczym dla informacji, które mogą być aktualizowane w czasie wykonywania. Zmienne umożliwiają wyszukiwanie i manipulowanie przechowywanymi danymi.
Wytyczne dotyczące nazewnictwa zmiennych:
o Zawsze zaczynaj nazwę zmiennej od litery lub podkreślenia (_). Dodatkowo w nazwach mogą występować litery "a-z" lub "A-Z" albo cyfry 0-9 i znak "_".
Peeks peeks, _peeks24 // prawidłowa zmienna
124peeks, 24peeks // nieprawidłowa zmienna
o Nigdy nie zaczynaj nazwy zmiennej od cyfry.
235peeks // niedozwolona zmienna
o W nazwie zmiennej rozróżniana jest wielkość liter.
peeks i Peeks to dwie różne zmienne
o Słowa kluczowe nie mogą być używane jako nazwy zmiennych.
o Nie ma ograniczeń co do długości nazwy zmiennej; zaleca się jednak, aby nie przekraczał 4-15 liter.
Deklarowanie zmiennej
Zmienne w języku programowania Go można deklarować na dwa sposoby.
Używanie słowa kluczowego var
Zmienne w Go są tworzone przy użyciu słowa kluczowego var określonego typu, połączonego z nazwą i nadanej wartości początkowej.
Składnia:
var nazwa_zmiennej typ = wyrażenie
Ważne notatki:
o W powyższej składni w definicji zmiennej można usunąć typ lub wyrażenie =, ale nie oba jednocześnie.
o Jeśli typ zostanie usunięty, inicjalizacja wartości w wyrażeniu określa typ zmiennej.
Przykład:
// Illustrate the concept of variable
package main
import "fmt"
func main() {
// Variable declared &
// initialized without the explicit type
var myvariable1 = 30
var myvariable2 = "PeeksofPeeks"
var myvariable3 = 37.80
// Display value and
// type of the variables
fmt.Printf("Value of myvariable1 is : %d\n",
myvariable1)
fmt.Printf("Type of myvariable1 is : %T\n",
myvariable1)
fmt.Printf("Value of myvariable2 is : %s\n",
myvariable2)
fmt.Printf("Type of myvariable2 is : %T\n",
myvariable2)
fmt.Printf("Value of myvariable3 is : %f\n",
myvariable3)
fmt.Printf("Type of myvariable3 is : %T\n",
myvariable3)
}
o Jeśli wyrażenie zostanie usunięte, zmienna będzie miała wartość zerową dla typu, na przykład zero dla liczb, fałsz dla logicznych, " " dla łańcuchów i zero dla typów interfejsowych i referencyjnych. W rezultacie w języku programowania Go nie ma pojęcia o niezainicjowanej zmiennej.
Przykład:
// Program to illustrate the concept of variable
package main
import "fmt"
func main() {
// Variable declared &
// initialized without the expression
var myvariable1 int
var myvariable2 string
var myvariable3 float64
// Display zero-value of the variables
fmt.Printf("Value of myvariable1 is : %d\n",
myvariable1)
fmt.Printf("Value of myvariable2 is : %s\n",
myvariable2)
fmt.Printf("Value of myvariable3 is : %f",
myvariable3)
}
o Używając typu, możemy zdefiniować kilka zmiennych tego samego typu w jednej deklaracji.
Przykład :
// Program to illustrate
// the concept of variable
package main
import "fmt"
func main() {
// Multiple variables of same type
// are declared & initialized in single line
var myvariable1, myvariable2, myvariable3 int
= 4, 554, 68
// Display values of the variables
fmt.Printf("Value of myvariable1 is : %d\n",
myvariable1)
fmt.Printf("Value of myvariable2 is : %d\n",
myvariable2)
fmt.Printf("Value of myvariable3 is : %d",
myvariable3)
}
o Jeśli usuniemy typ, możemy zdefiniować wiele zmiennych różnych typów w jednej deklaracji. Zainicjowane wartości wskazują typ zmiennej.
Przykład:
// Program to illustrate
// the concept of variable
package main
import "fmt"
func main() {
// Multiple variables of different types
// are declared and initialized in single line
var myvariable1, myvariable2, myvariable3 = 4,
"CFG", 69.56
// Display value &
// type of variables
fmt.Printf("Value of myvariable1 is : %d\n",
myvariable1)
fmt.Printf("Type of myvariable1 is : %T\n",
myvariable1)
fmt.Printf("\nValue of the myvariable2 is : %s\n",
myvariable2)
fmt.Printf("Type of the myvariable2 is : %T\n",
myvariable2)
fmt.Printf("\nThe value of the myvariable3 is :
%f\n",
myvariable3)
fmt.Printf("Type of the myvariable3 is : %T\n",
myvariable3)
}
o Funkcja wywołująca, która zwraca wiele wartości, pozwala nam zainicjować zestaw zmiennych.
Przykład:
// Here, os.Open function return a
// file in x variable and an error
// in y variable
var x, y = os.Open(name)
Korzystanie z krótkiej deklaracji zmiennej
Krótka deklaracja zmiennej służy do definiowania i inicjalizacji zmiennych lokalnych w funkcjach.
Składnia:
nazwa-zmiennej:= wyrażenie
Uwaga: Proszę nie mylić := i =, ponieważ := to deklaracja, a = to przypisanie.
Ważne notatki:
o Typ wyrażenia decyduje o typie zmiennej w poprzednim wyrażeniu.
Przykład:
// Program to illustrate
// the concept of variable
package main
import "fmt"
func main()
{
// Using short-variable declaration
myvar1 := 37
myvar2 := "PeeksofPeeks"
myvar3 := 36.63
// Display value and type of the variables
fmt.Printf("Value of myvar1 is : %d\n", myvar1)
fmt.Printf("Type of myvar1 is : %T\n", myvar1)
fmt.Printf("\nValue of myvar2 is : %s\n", myvar2)
fmt.Printf("Type of myvar2 is : %T\n", myvar2)
fmt.Printf("\nValue of myvar3 is : %f\n", myvar3)
fmt.Printf("Type of myvar3 is : %T\n", myvar3)
}
o Ze względu na ich zwięzłość i wszechstronność, większość zmiennych lokalnych jest definiowana i inicjowana przy użyciu krótkich deklaracji zmiennych.
o Zmienne z deklaracją var są używane dla zmiennych lokalnych, które wymagają jawnego typu, różniącego się od wyrażenia inicjującego lub zmiennych, których wartości są przypisywane później, a wartość zainicjowana jest nieistotna.
o Używając krótkiej deklaracji zmiennej, możemy zadeklarować kilka zmiennych w jednej deklaracji.
Przykład:
// Go program to illustrate
// concept of variable
package main
import "fmt"
func main()
{
// Using short variable declaration
// Multiple variables of the same types
// are declared & initialized in single line
myvar1, myvar2, myvar3 := 830, 44, 66
// Display value and
// type of variables
fmt.Printf("Value of myvar1 is : %d\n", myvar1)
fmt.Printf("Type of myvar1 is : %T\n", myvar1)
fmt.Printf("\nValue of myvar2 is : %d\n", myvar2)
fmt.Printf("Type of myvar2 is : %T\n", myvar2)
fmt.Printf("\nValue of myvar3 is : %d\n", myvar3)
fmt.Printf("Type of myvar3 is : %T\n", myvar3)
}
o Funkcja wywołująca może zainicjować grupę zmiennych, które zwracają wiele wartości w krótkiej deklaracji zmiennej.
Przykład :
// os.Open function return
// a file in x variable and an
// error in y variable
x, y := os.Open(name)
o Krótka deklaracja zmiennej zachowuje się podobnie do przypisania tylko wtedy, gdy odnosi się do wcześniej zdefiniowanych zmiennych w tym samym bloku leksykalnym. Deklaracje zmiennych w bloku zewnętrznym są ignorowane. Jak pokazano w poniższym przykładzie, co najmniej jedna zmienna jest nową zmienną utworzoną z tych dwóch zmiennych.
Przykład:
// Program to illustrate
// the concept of variable
package main
import "fmt"
func main() {
// Using the short variable declaration
// short variable declaration acts
// as an assignment for the myvar2 variable
// because same variable present in same block
// so the value of myvar2 is changed from 55 to 100
myvar1, myvar2 := 39, 55
myvar3, myvar2 := 55, 100
// If we try to run the commented lines,
// then compiler will gives the error because
// these variables are already defined
// myvar1, myvar2 := 53, 57
// myvar2:= 210
// Display the values of the variables
fmt.Printf("Value of myvar1 and myvar2 is : %d
%d\n",
myvar1, myvar2)
fmt.Printf("Value of myvar3 and myvar2 is : %d
%d\n",
myvar3, myvar2)
}
o Możemy zdefiniować wiele zmiennych różnego rodzaju w jednej deklaracji przy użyciu krótkiej deklaracji zmiennej. Wyrażenie określa typ tych zmiennych.
Przykład:
// Program to illustrate
// the concept of variable
package main
import "fmt"
func main() {
// Using the short variable declaration
// Multiple variables of the different types
// are declared and initialized in single line
myvar1, myvar2, myvar3 := 700, "Peeks", 48.56
// Display value and type of the variables
fmt.Printf("Value of myvar1 is : %d\n", myvar1)
fmt.Printf("Type of myvar1 is : %T\n", myvar1)
fmt.Printf("\nValue of myvar2 is : %s\n", myvar2)
fmt.Printf("Type of myvar2 is : %T\n", myvar2)
fmt.Printf("\nValue of myvar3 is : %f\n", myvar3)
fmt.Printf("Type of myvar3 is : %T\n", myvar3)
}
STAŁE
Jak wskazuje słowo CONSTANT, jest ono ustalone; podobnie w językach programowania po zadeklarowaniu wartości stałej nie można jej dalej zmieniać. Stałe mogą być dowolnym podstawowym rodzajem danych, takim jak stała całkowita, stała zmiennoprzecinkowa, stała znakowa lub ciąg znaków.
Jak powinniśmy zadeklarować?
Stałe są definiowane podobnie jak zmienne, ale ze słowem kluczowym const jako prefiksem określającym stałą określonego typu. Nie da się tego opisać za pomocą składni :=.
Przykład:
package main
import "fmt"
const Pi = 3.14
func main()
{
const POP = "PeeksofPeeks"
fmt.Println("Hello", world)
fmt.Println("Happy", Pi, "Day")
const Correct= true
fmt.Println("Go rules?", Correct)
}
Niewpisane i wpisane stałe liczbowe
Wpisane stałe zachowują się jak niezmienne zmienne i mogą wchodzić w interakcje tylko ze zmiennymi tego samego typu, ale stałe bez typu zachowują się jak literały i wchodzą w interakcje z podobnymi zmiennymi. W Go stałe mogą być określane z typem lub bez niego. Poniżej znajduje się przykład wpisanych i niewpisanych stałych numerycznych, zarówno nazwanych, jak i bezimiennych.
const untypedInteger = 321
const untypedFloating typed = 321.12
const typedInteger int = 321
const typedFloatingPoint float64 = 321.12
Poniżej znajduje się lista stałych języka Go:
o Stała liczbowa (stała całkowita, stała zmiennoprzecinkowa i stała zespolona)
o Stała logiczna
o Literały łańcuchowe
Stała numeryczna
Stałe numeryczne to wartości o wysokiej precyzji. Ponieważ Go jest językiem o typach statycznych, operacje łączące typy numeryczne są niedozwolone. Nie możemy dodać float64 ani nawet int32 do int. Niemniej jednak wolno pisać 1e6*time. Po drugie, czyli matematyka. 1('t'+2.0) lub nawet Exp(1). Stałe, w przeciwieństwie do zmiennych, działają w Go jak zwykłe liczby. Istnieją trzy typy stałych numerycznych: całkowite, złożone i zmiennoprzecinkowe.
Stała całkowita
o Podstawa lub podstawa jest określona przez przedrostek: 0x lub 0X dla szesnastkowego, 0 dla ósemkowego i nic dla dziesiętnego.
o Literał całkowity może dodatkowo zawierać sufiks, który jest mieszanką U (duże litery) i L (wielkie litery), wskazując, że jest on bez znaku lub długi.
o Może to być stała w postaci dziesiętnej, ósemkowej lub szesnastkowej.
o Int może przechowywać co najwyżej 64-bitową liczbę całkowitą, a czasami mniej.
Oto kilka przykładów stałej całkowitoliczbowej:
85 : dziesiętny
0213 : ósemkowy
0x4b : szesnastkowy
30 : wewn
30u : bez znaku wewn
30 l : długi
30ul: długi bez znaku
212 : Prawny
215u : Prawne
0xFeeL: legalne
078 : Nielegalne: 8 nie jest cyfrą ósemkową
032UU: Nielegalne: nie można powtórzyć sufiksu
Stała zespolona Stałe zespolone działają bardzo podobnie do stałych zmiennoprzecinkowych. Jest to uporządkowana lub rzeczywista para stałych całkowitych (lub parametrów), oddzielona przecinkiem i zawarta w nawiasach okrągłych. Pierwsza stała reprezentuje rzeczywisty składnik, podczas gdy druga reprezentuje część urojoną. COMPLEX*8 to stała zespolona, która wymaga 8 bajtów pamięci.
Przykład:
(0.0, 0.0) (-123.456E+30, 987.654E-29)
Stała zmiennoprzecinkowa Część całkowita, kropka dziesiętna, część ułamkowa i część wykładnicza składają się na stałą typu zmiennoprzecinkowego. Stałe zmiennoprzecinkowe mogą być reprezentowane w postaci dziesiętnej lub wykładniczej. Wyrażając w postaci dziesiętnej, musimy uwzględnić kropkę dziesiętną, wykładnik lub oba. A w przypadku stosowania formy wykładniczej część całkowita, ułamkowa lub obie części muszą zawierać. Oto kilka przykładów stałych typu Floating:
3.14159 : Poprawny
314159E-5L : Informacje poprawne
510E : Niedozwolone: niepełny wykładnik
210f : Niedozwolone: brak miejsca dziesiętnego lub wykładnika
.e55 : Niedozwolone: brak liczby całkowitej lub ułamka
Literały łańcuchowe
Go obsługuje dwie formy literałów łańcuchowych: " " (styl podwójnego cudzysłowu) i " " (cudzysłów wsteczny). Operatorów + i += można używać do łączenia łańcuchów. Znaki w łańcuchu są porównywalne z literałami znakowymi, ponieważ są zwykłymi znakami, sekwencjami specjalnymi i znakami uniwersalnymi. I to jest przypadek nieokreślony. Typy ciągów z wartościami zerowymi to puste ciągi, które mogą być reprezentowane literalnie przez " " lub ". Wszystkie typy łańcuchów można porównywać za pomocą operatorów, takich jak ==,!= i (do porównywania tych samych typów)
Składnia:
type _string struct
{
elements *byte // the underlying bytes
len int //the number of bytes
}
Przykład :
"hello, peeksofpeeks"
"hello, \
peeksofpeeks"
"hello " "peeks" "ofpeeks"
Wszystkie trzy z powyższych stwierdzeń są w tym kontekście podobne w tym sensie, że brakuje im określonego typu.
Przykład :
package main
import "fmt"
func main()
{
const X = "POP"
var Y = "PeeksofPeeks"
// Concat strings.
var helloEveryone = X+ " " + Y
helloEveryone += "!"
fmt.Println(helloEveryone)
// Compare strings.
fmt.Println(X == "POP")
fmt.Println(Y < X)
}
Stała logiczna
Stałe łańcuchowe i stałe boolowskie są typami stałych. Podąża za tymi samymi wytycznymi, co stała łańcuchowa. Główna różnica polega na tym, że zawiera dwie stałe bez typu, true i false.
Przykład:
package main
import "fmt"
const Pi = 3.14
func main()
{
const trueConst = true
// Type definition using the type keyword
type myBool bool
var defaultBool = trueConst // allowed
var customBool myBool = trueConst // allowed
// defaultBool = customBool // not allowed
fmt.Println(defaultBool)
fmt.Println(customBool)
}
ZMIENNY ZAKRES W Go
Zasięg zmiennej można opisać jako obszar programu, w którym dostępna jest określona zmienna. Zmienną można zadeklarować w klasie, metodzie, pętli lub innej strukturze. Podobnie jak w C/C++, wszystkie identyfikatory w GoLangu mają zasięg leksykalny (lub statyczny), co oznacza, że zakres zmiennej może zostać określony w czasie kompilacji. Alternatywnie zmienną można wywołać tylko z poziomu bloku kodu, w którym jest zdefiniowana. Reguły zakresu zmiennych w GoLang można podzielić na dwa typy w zależności od tego, gdzie zmienne są deklarowane:
o Zmienne lokalne (deklarowane wewnątrz bloku)
o Zmienne globalne (deklarowane poza blokiem)
Zmienne lokalne
o Typ zmiennych zdefiniowanych w funkcji lub bloku to zwane zmiennymi lokalnymi. Poza funkcją lub blokiem są niedostępne.
o Zmienne te można również zadeklarować w funkcji for, while, i podobne stwierdzenia.
o Dostęp do tych zmiennych można jednak uzyskać za pomocą zagnieżdżonych bloków kodu w ramach funkcji.
o Zmienne blokowe to inna nazwa tych zmiennych.
o Błąd kompilacji wystąpi, jeśli te zmienne zostaną zadeklarowane dwukrotnie z tą samą nazwą w tym samym zakresie.
o Po zakończeniu wykonywania funkcji zmienne te nie są już obecne.
o Zmienna określona poza pętlą jest również dostępna w zagnieżdżonych pętlach. Oznacza to, że zmienna globalna będzie dostępna dla wszystkich metod i pętli. Pętla i funkcja wewnątrz funkcji będzie mogła uzyskać dostęp do zmiennej lokalnej.
o Zmienna zadeklarowana w ciele pętli nie jest widoczna na zewnątrz ciała pętli.
Przykład:
// Program to illustrate the local variables
package main
import "fmt"
// main function
func main() { // from here the local level scope
of main function starts
// local variables inside the main function
var myvariable1, myvariable2 int = 90, 47
// Display values of the variables
fmt.Printf("Value of myvariable1 is : %d\n",
myvariable1)
fmt.Printf("Value of myvariable2 is : %d\n",
myvariable2)
} // here the local level scope of main function
ends
Zmienne globalne
o Zmienne globalne są określane poza funkcją lub blokiem.
o Są one dostępne przez cały czas trwania programu.
o Są one deklarowane poza funkcjami lub blokami na początku programu.
o Są one dostępne z dowolnego miejsca w programie.
Przykład:
// Program to illustrate the global variables
package main
import "fmt"
// the global variable declaration
var myvariable1 int = 120
func main() { // from here the local level scope
starts
// the local variables inside the main function
var myvariable2 int = 210
// Display value of global variable
fmt.Printf("Value of Global myvariable1 is :
%d\n",
myvariable1)
// Display value of local variable
fmt.Printf("Value of Local myvariable2 is : %d\n",
myvariable2)
// calling function
display()
} // local level scope ends
// taking function
func display() { // the local level starts
// Display value of global variable
fmt.Printf("Value of Global myvariable1 is :
%d\n",
myvariable1)
} // the local scope ends here
Uwaga: Co się stanie, jeśli w funkcji pojawi się zmienna lokalna o takiej samej nazwie jak zmienna globalna? Rozwiązanie jest proste: kompilator będzie faworyzował zmienną lokalną. Gdy deklarowane są dwie podobne zmienne o tej samej nazwie, kompilator zwykle generuje błąd czasu kompilacji. Jeśli jednak zmienne są określone w różnych zakresach, kompilator je zaakceptuje. Kompilator będzie poprzedzał zmienną lokalną, gdy zostanie zadeklarowana zmienna lokalna o takiej samej nazwie jak zmienna globalna.
o W poniższym przykładzie możemy zobaczyć dane wyjściowe. Ponieważ wartość myvariable1 w funkcji main wynosi 210. W rezultacie zmienna lokalna zdecydowanie preferuje zmienną globalną.
Przykład:
// Program to show the compiler giving preference
// to local variable over a global variable
package main
import "fmt"
// the global variable declaration
var myvariable1 int = 120
func main() { // from here the local level scope
starts
// local variables inside main function
// it is same as a global variable
var myvariable1 int = 210
// Display value
fmt.Printf("Value of myvariable1 is : %d\n",
myvariable1)
} // here the local level scope ends
DEKLARACJA WIELU ZMIENNYCH
Pojedyncza instrukcja może służyć do deklarowania wielu zmiennych. Składnia deklaracji wielu zmiennych to var nazwa1, nazwa2 typ = wartość początkowa1, wartość początkowa2.
Przykład:
package main
import "fmt"
func main() {
var width, height int = 120, 60 //declaring
multiple variables
fmt.Println("width :", width, "height :", height)
}
Jeśli zmienne mają wartość początkową, typ można pominąć. Ponieważ zmienne w poprzednim programie mają wartości początkowe, typ int może usunąć.
Przykład:
Na przykład powyższe oprogramowanie wydrukuje w rezultacie szerokość 120 i wysokość 60. Jest całkiem jasne, że powinieneś już się domyślić, że jeśli nie określono wartości początkowej szerokości i wysokości, ustawimy ją na 0.
Przykład:
package main
import "fmt"
func main() {
var width, height int
fmt.Println("width :", width, "height :", height)
width = 120
height = 60
fmt.Println("new width :", width, "new height
:", height)
}
Może się zdarzyć, że chcemy zdefiniować zmienne kilku rodzajów w jednym zdaniu. Składnia służąca do tego jest wyjaśniona poniżej:
var (
nme1 = initialvalue1
nme2 = initialvalue2
)
Poniższy program deklaruje zmienne różnego rodzaju przy użyciu składni opisanej powyżej.
package main
import "fmt"
func main() {
var (
name = "natasha"
age = 27
height int
)
fmt.Println("my name :", name, ", age :", age,
"and height :", height)
}
Tutaj definiujemy nazwę zmiennej łańcuchowej, zmienną int wiek i zmienną int wysokość.
Deklaracja skrócona
Go ma również bardziej zwarte podejście do deklarowania zmiennych. Nazywa się to instrukcją skróconą i wykorzystuje operator :=. Skróconą formą deklarowania zmiennej jest nazwa := wartość początkowa. Poniższy program deklaruje zmienną count o wartości 12 przy użyciu składni skróconej. Ponieważ count zostało rozpoczęte od wartości całkowitej 12, Go wywnioskuje, że jest typu int.
package main
import "fmt"
func main() {
count := 12
fmt.Println("Count =",count)
}
Wiele zmiennych można również zadeklarować w jednym wierszu przy użyciu składni skróconej.
package main
import "fmt"
func main() {
name, age := "natasha", 27 //short hand
declaration
fmt.Println("my name :", name, "age :", age)
}
Poprzedni program definiuje dwie zmienne typu string i int, odpowiednio. Jeśli wykonamy lub uruchomimy powyższy program, zobaczymy wydrukowane moje imię, Natasza i wiek, 27. Deklaracja skrócona wymaga przypisania wartości początkowych wszystkim zmiennym po lewej stronie przypisania. Następująca aplikacja zwróci błąd niezgodności przypisania: dwie zmienne, ale tylko jedna wartość. Wynika to z faktu, że wieku nie przypisano wartości.
package main
import "fmt"
func main() {
name, age := "natasha" //error
fmt.Println("my name :", name, "age :", age)
}
Tylko wtedy, gdy co najmniej jedna zmienna po lewej stronie := jest nowo zdefiniowana, można użyć składni skróconej. Pomyśl o następującym programie:
package main
import "fmt"
func main() {
x, y := 30, 10 // declare variables x and y
fmt.Println("x is", x, "y is", y)
y, z := 50, 60 // y is already declared but z is
new
fmt.Println("y is", y, "z is", z)
y, z = 70, 80 // assign new values to already
declared variables y and z
fmt.Println("changed y is", y, "z is", z)
}
Natomiast jeśli wykonamy następujący program:
package main
import "fmt"
func main() {
x, y := 20, 30 //x and y declared
fmt.Println("x is", x, "y is", y)
x, y := 40, 50 //error, no new variables
}
Wygeneruje komunikat o błędzie. Po lewej stronie := nie ma nowych zmiennych, ponieważ zmienne aib zostały już zadeklarowane. Brak nowych zmiennych po lewej stronie := w wierszu nr. 6. Zmienne mogą mieć również wartości obliczane w czasie wykonywania.
Pomyśl o następującym programie:
package main
import (
"fmt"
"math"
)
func main() {
x, y := 145.8, 543.8
z := math.Min(x, y)
fmt.Println("Minimum value :", z)
}
Math to pakiet w powyższym programie, a Min to funkcja w tym pakiecie. Musimy wiedzieć, że wartość z jest określana w czasie wykonywania i jest równa sumie x i y. Zmiennym określonym jako należące do jednego typu nie można przypisać wartości innego typu, ponieważ Go jest ściśle typowany. Ponieważ wiek jest określony jako typ int, a my próbujemy przypisać wartość ciągu, poniższy program wyświetli błąd informujący, że nie możemy użyć "natasha" (typ ciąg) jako typu int w przypisaniu.
package main
func main() {
age := 27 // age is int
age = "natasha" // error since we are trying to
assign the string to a variable of type int
}
Operatory i struktury kontrolne
Operatory w Go
Operatory są budulcem każdego języka programowania. W efekcie bez użycia operatorów funkcjonalność języka Go jest niepełna. Operatory pozwalają nam wykonywać wiele działań na operandach. Operatory w języku programowania Go są klasyfikowane na podstawie ich funkcjonalności:
o Operatory arytmetyczne
o Operatorzy relacyjni
o Różni operatorzy
o Operatory bitowe
o Operatorzy przypisania
o Operatory logiczne
Operatory arytmetyczne
W Go są one używane do wykonywania operacji arytmetycznych/matematycznych na operandach:
o Dodawanie: Operator "+" łączy ze sobą dwa operandy. Na przykład x+y.
o Odejmowanie: Operator "-" bierze dwa operandy i odejmuje je. Na przykład x-y.
o Mnożenie: Znak "*" służy do mnożenia dwóch operandów. Na przykład, x*y.
o Dzielenie: Operator "/" dzieli pierwszy operand przez drugi operand. Jako przykład rozważmy x/y.
o Moduł: Kiedy pierwszy operand jest dzielony przez drugi, zwracana jest reszta operatora "%". Na przykład x procent y.
Nota bene: -, +, !, &, * i - są również znane jako operatory jednoargumentowe i mają wyższy priorytet. Ponieważ operatory ++ i -- pochodzą z instrukcji, a nie z wyrażeń; znajdują się poza hierarchią operatorów.
Przykład:
// Program to illustrate the
// use of the arithmetic operators
package main
import "fmt"
func main()
{
x:= 37
y:= 22
// Addition
result1:= x + y
fmt.Printf("Result of x + y = %d", result1)
// Subtraction
result2:= x - y
fmt.Printf("\nResult of x - y = %d", result2)
// Multiplication
result3:= x * y
fmt.Printf("\nResult of x * y = %d", result3)
// Division
result4:= x / y
fmt.Printf("\nResult of x / y = %d", result4)
// Modulus
result5:= x % y
fmt.Printf("\nResult of x %% y = %d", result5)
}
Operatory relacyjne>
Podczas porównywania dwóch wartości stosowane są operatory relacyjne. Przyjrzyjmy się im:
o Operator "==" (równy) określa, czy dwa operandy są równe. W takim przypadku zwraca wartość true. Jeśli nie, zwraca false. 6==6 zwróci na przykład prawdę.
o Operator "!=" określa, czy dwa podane operandy są równe, czy nie. Jeśli tak, zwraca wartość true. Jeśli nie, zwraca false. Jest to logiczny odpowiednik operatora "==". 6!=6 zwróci na przykład fałsz.
o Operator ">" (Większy niż) określa, czy pierwszym argumentem jest większy niż drugi. W takim przypadku zwraca wartość true. Jeśli nie, zwraca fałsz. 7>6 da na przykład prawdę.
o Operator "<" (Mniej niż) określa, czy pierwszy operand jest mniejszy niż drugi. W takim przypadku zwraca wartość true. Jeśli nie, zwraca false. Na przykład 6<4 zwróci fałsz.
o Operator "?" (Większy niż równy) określa, czy pierwszy operand jest większy lub równy drugiemu operandowi, a następnie zwraca prawdę. Jeśli nie, zwraca false. 6?6 zwróci na przykład prawdę. o Operator "?" (najmniejszy niż równy) określa, czy pierwszy operand jest mniejszy lub równy drugiemu operandowi, a następnie zwraca wartość true. Jeśli nie, zwraca false. Na przykład 6?6 również zwróci wartość true.
Przykład:
// Program to illustrate
// the use of relational operators
package main
import "fmt"
func main() {
x:= 38
y:= 25
// '=='(Equal To)
result1:= x == y
fmt.Println(result1)
// '!='(Not Equal To)
result2:= x != y
fmt.Println(result2)
// '<'(Less Than)
result3:= x < y
fmt.Println(result3)
// '>'(Greater Than)
result4:= x > y
fmt.Println(result4)
// '>='(Greater Than Equal To)
result5:= x >= y
fmt.Println(result5)
// '<='(Less Than Equal To)
result6:= x <= y
fmt.Println(result6)
}
Operatory logiczne
Służą do zintegrowania dwóch lub więcej warunków/ograniczeń lub uzupełnienia oceny pierwotnego warunku.
o Logiczne AND: Operator && zwraca wartość true, gdy spełnione są oba rozważane warunki. Jeśli nie, zwraca false. x && y, na przykład, zwraca wartość true, gdy zarówno x, jak i y są prawdziwe (tj. niezerowe).
o Logiczne LUB: Gdy spełniony jest jeden lub oba wymagania, operator "||" zwraca wartość true. Jeśli nie, zwraca false. Na przykład x || y zwraca true, jeśli x lub y jest prawdziwe (tj. niezerowe). Oczywiście zwraca wartość true, jeśli zarówno x, jak i y są prawdziwe.
o Logiczne NIE: Jeśli dany warunek jest spełniony, operator "!" zwraca prawdę. Jeśli nie, zwraca false. !x, na przykład, zwraca wartość true, jeśli a jest fałszywe, czyli gdy x=0.
Przykład:
// Program to illustrate
//the use of logical operators
package main
import "fmt"
func main() {
var x int = 26
var y int = 65
if(x!=y && x<=y){
fmt.Println("True")
}
if(x!=y || x<=y){
fmt.Println("True")
}
if(!(x==y)){
fmt.Println("True")
}
}
Operatory bitowe
W języku programowania Go 6 operatorów bitowych działa na poziomie bitowym lub wykonuje operacje bit po bicie. Operatory bitowe to:
o & (bitowe AND): Pobiera dwa operandy i wykonuje operację AND na każdym bicie dwóch liczb. AND zwraca 1 tylko wtedy, gdy oba bity są równe 1.
o | (bitowe LUB): Pobiera dwa operandy i wykonuje LUB na każdym bicie dwóch liczb całkowitych. LUB zwraca wartość 1, jeśli jeden z dwóch bitów ma wartość 1.
o ^ (bitowe XOR): Pobiera dwa operandy i wykonuje XOR na każdym bicie dwóch liczb. Jeśli dwa bity są różne, wynikiem operacji XOR jest 1.
o << (przesunięcie w lewo): przyjmuje dwie liczby całkowite, przesuwa w lewo bity pierwszego operandu, a drugi operand określa liczbę przesunąć pozycji.
o >> (przesunięcie w prawo): pobiera dwie liczby, przesuwa bity pierwszego operandu w prawo, a liczba miejsc do przesunięcia jest określana przez drugi operand.
o &^ (AND NOT): Jest to prosty operator.
Przykład:
// Program to illustrate
// the use of bitwise operators
package main
import "fmt"
func main() {
x:= 34
y:= 20
// & (bitwise AND)
result1:= x & y
fmt.Printf("Result of x & y = %d", result1)
// | (bitwise OR)
result2:= x | y
fmt.Printf("\nResult of p | q = %d", result2)
// ^ (bitwise XOR)
result3:= p ^ q
fmt.Printf("\nResult of x ^ y = %d", result3)
// << (left shift)
result4:= x << 1
fmt.Printf("\nResult of x << 1 = %d", result4)
// >> (right shift)
result5:= x >> 1
fmt.Printf("\nResult of x >> 1 = %d", result5)
// &^ (AND NOT)
result6:= x &^ y
fmt.Printf("\nResult of x &^ y = %d", result6)
}
Operatory przypisania
Podczas przypisywania wartości do zmiennej stosowane są operatory przypisania. Lewy operand operatora przypisania jest zmienną, a prawy operand operatora przypisania jest wartością. Wartość po prawej stronie musi mieć ten sam typ danych co zmienna po lewej stronie, w przeciwnym razie kompilator zgłosi błąd. Oto przykłady operatorów przypisania:
o "=" (Proste przypisanie): Najbardziej podstawowy operator przypisania. Wartość po prawej stronie jest przypisywana do zmiennej po lewej stronie za pomocą tego operatora.
o "+=" (Dodaj przypisanie): Kombinacja operatorów "+" i "=". Ten operator najpierw dodaje zmienną po lewej stronie bieżącej wartości do prawej, a następnie przypisuje wynik do zmiennej po lewej stronie.
o "-=" (odejmowanie przypisania): Kombinacja operatorów "?" i "=". Ten operator odejmuje bieżącą wartość zmiennej po lewej stronie od prawej, a następnie przypisuje wynik zmiennej po lewej stronie.
o "*=" (przypisanie mnożenia): Kombinacja operatorów "*" i "=". Ten operator najpierw mnoży zmienną po lewej przez prawą, a następnie przypisuje wynik do lewej zmiennej.
o "/=" (przypisanie dzielenia): Kombinacja operatorów "/" i "=". Ten operator dzieli zmienną po lewej stronie bieżącą wartość przez wartość po prawej stronie, a następnie przypisuje wynik zmiennej po lewej stronie.
o "%=" (przypisanie modułu): Ten operator łączy w sobie operatory "%" i "=". Operator ten mnoży aktualną wartość zmiennej po lewej przez prawą, a następnie przypisuje wynik do lewej zmiennej.
o "&=" (przypisanie bitowe AND): kombinacja "&" i "=" operatorzy. Ten operator "Bitwise AND" bieżąca wartość do lewej zmiennej do prawej przed przypisaniem wyniku do lewej zmiennej.
o "=" (bitowe wyłączne LUB): Kombinacja operatorów "=" i "=". Ten operator "Bitwise Exclusive OR" przestawia bieżącą wartość lewej zmiennej na prawą przed przypisaniem wyniku do lewej zmiennej.
o "|=" (bitowo włącznie OR): Kombinacja operatorów "|" i "=". Ten operator "Bitwise Inclusive OR" przestawia bieżącą wartość lewej zmiennej na prawą przed przypisaniem wyniku do lewej zmiennej.
Przykład:
// Program to illustrate
// the use of assignment operators
package main
import "fmt"
func main()
{
var x int = 49
var y int = 54
// "="(Simple Assignment)
x = y
fmt.Println(p)
// "+="(Add Assignment)
x += y
fmt.Println(x)
//"-="(Subtract Assignment)
x-=y
fmt.Println(x)
// "*="(Multiply Assignment)
x*= y
fmt.Println(x)
// "/="(Division Assignment)
x /= y
fmt.Println(x)
// "%="(Modulus Assignment)
x %= y
fmt.Println(x)
}
Różne operatorzy
o &: Ten operator zwraca adres zmiennej.
o *: Ten operator zwraca wskaźnik do zmiennej.
o <-: Otrzymano nazwę tego operatora. Służy do pobierania wartości z kanału.
Przykład:
// Program to illustrate
// the use of Misc Operators
package main
import "fmt"
func main() {
x := 6
// Using address of operator(&) and
// pointer indirection(*) operator
y := &x
fmt.Println(*y)
*y = 7
fmt.Println(x)
}
INSTRUKCJE STERUJĄCE
Programista musi zdefiniować jeden lub więcej warunków, które mają być ocenione lub przetestowane przez program, instrukcję lub instrukcje, które zostaną wykonane, jeśli warunek zostanie uznany za prawdziwy, oraz opcjonalnie dalsze instrukcje, które zostaną wykonane, jeśli warunek zostanie uznany za fałszywy. Poniżej przedstawiono ogólną formę wspólnych ram podejmowania decyzji obecnych w większości języków programowania.
Język programowania Go obsługuje następujące instrukcje decyzyjne.
Nr: instrukcja i opis
1: instrukcja if: Po wyrażeniu boolowskim następuje jedna lub więcej instrukcji w instrukcji if.
2 : instrukcja if...else : Gdy wyrażenie boolowskie jest fałszywe, po instrukcji if następuje opcjonalna instrukcja else.
3 : zagnieżdżone instrukcje if : Instrukcja if lub else if może być używana wewnątrz innej instrukcji if lub else if.
4 : instrukcja switch : instrukcja switch sprawdza zmienną pod kątem równości względem zbioru wartości.
5 : instrukcja select : instrukcja select jest podobna do instrukcji switch; jednak opisy przypadków odnoszą się do komunikacji kanałowej.
Instrukcja if
Jest to najprostsze stwierdzenie decyzyjne. Służy do decydowania, czy określona instrukcja lub blok instrukcji zostanie wykonany, tj. jeśli dany warunek jest prawdziwy, to blok instrukcji zostanie wykonany, w przeciwnym razie nie.
Składnia:
if (warunek)
{
// Instrukcja do wykonania, jeśli warunek jest prawdziwy
}
Przykład :
// Program to illustrate
//the use of if statement
package main
import "fmt"
func main() {
// taking local variable
var v int = 800
// using the if statement for
// checking condition
if(v < 2000) {
// print following if
// condition evaluates to true
fmt.Printf("v is less than 2000\n")
}
fmt.Printf("Value of v is : %d\n", v)
}
Instrukcja if
else
Instrukcja if sama w sobie informuje nas, że warunek jest prawdziwy, zostanie wykonany blok instrukcji; jeśli warunek jest fałszywy, blok instrukcji nie zostanie wykonany. Ale co, jeśli warunek jest fałszywy i chcemy zrobić coś innego? W tym momencie pojawia się instrukcja else. Gdy warunek jest fałszywy, możemy użyć instrukcji else w połączeniu z instrukcją if, aby uruchomić blok kodu.
Składnia:
if (warunek)
{
// Wykonuje ten blok if
// warunek jest prawdziwy
} w przeciwnym razie {
// Wykonuje ten blok if
// warunek jest fałszywy
}
Przykład :
// Program to illustrate
// the use of if...else statement
package main
import "fmt"
func main() {
// taking a local variable
var v int = 2400
// using the if statement for
// checking condition
if(v < 2000) {
// print following if
// the condition evaluates to true
fmt.Printf("v is less than 2000\n")
} else {
// print following if
// the condition evaluates to true
fmt.Printf("v is greater than 2000\n")
}
}
Zagnieżdżona instrukcja if
W Go zagnieżdżone if jest instrukcją if, która jest celem innego wyrażenia if lub else. Instrukcja if zagnieżdżona w innej instrukcji if jest nazywana zagnieżdżoną instrukcją if. Tak, możemy zagnieżdżać instrukcje if w instrukcjach if w GoLang. Innymi słowy, możemy zagnieździć instrukcję if w innej instrukcji if.
Składnia:
if (condition1) {
// Executes when the condition1 is true
if (condition2) {
// Executes when the condition2 is true
}
}
Przykład :
// Program to illustrate
// the use of nested if statement
package main
import "fmt"
func main() {
// taking the two local variable
var v1 int = 500
var v2 int = 800
// using if statement
if( v1 == 600 ) {
// if condition is true then
// check the following
if( v2 == 800 ) {
// if the condition is true
// then display following
fmt.Printf("Value of v1 is 500 and v2 is
800\n" );
}
}
}
Drabinka ifjeśli
else
if
Użytkownik może tutaj wybierać spośród wielu alternatyw. Instrukcje if są wykonywane w podanej kolejności. Gdy spełniony jest jeden z warunków, wykonywana jest instrukcja związana z tym if; reszta drabiny jest pomijana. Jeśli żadne z wymagań nie jest spełnione, wykonywana jest ostatnia instrukcja else.
Ważne notatki:
o Instrukcja if może mieć wartość zero lub jeden i musi wystąpić po każdej innej instrukcji if.
o Instrukcja else if w instrukcji if może zawierać od zera do wielu innych instrukcji if i musi wystąpić przed klauzulą else.
o Jeśli instrukcja else if powiedzie się, nie ma potrzeby wypróbowywania żadnej z pozostałych instrukcji else if lub else.
Składnia:
if(condition_1) {
// this block will execute when the
condition_1 is true
} else if(condition_2) {
// this block will execute when the condition2
is true
}
.
else {
// this block will execute when none
// of condition is true
}
Przykład:
// Program to illustrate
// the use of if..else..if ladder
package main
import "fmt"
func main() {
// taking a local variable
var v1 int = 800
// checking condition
if(v1 == 120) {
// if condition is true then
// display following */
fmt.Printf("Value of v1 is 120\n")
} else if(v1 == 250) {
fmt.Printf("Value of a is 250\n")
} else if(v1 == 310) {
fmt.Printf("Value of a is 310\n")
} else {
// if none of the conditions is true
fmt.Printf("None of values is matching\n")
}
}
Przejdź do pętli GoLang
Język programowania Go ma tylko jedną pętlę, którą jest pętla for. Pętla for jest formą struktury kontroli powtórzeń, która pozwala nam zaprojektować pętlę, która zostanie wykonana określoną liczbę razy. Ta pętla for może być używana na kilka sposobów w języku programowania Go, w tym:
1. Jak najbardziej podstawowa pętla for: jest porównywalna z tym, co widzimy w innych językach programowania, takich jak C, C++, C#, Java itp.
Składnia:
for initialization; condition; post{
// statement
}
Tutaj instrukcja inicjalizacji jest opcjonalna i jest uruchamiana przed rozpoczęciem pętli for. Instrukcja inicjalizacji jest zawsze zawarta w instrukcji podstawowej, takiej jak deklaracje zmiennych, instrukcje inkrementacji lub przypisania lub wywołania funkcji. Instrukcja warunku zawiera wyrażenie logiczne oceniane na początku każdej iteracji pętli. Pętla jest wykonywana, jeśli wartość instrukcji warunkowej jest prawdziwa. Instrukcja post jest wykonywana po treści pętli for. Po oświadczeniu post, oświadczenie warunku jest ponownie oceniane; jeśli wartość instrukcji warunkowej jest fałszywa, pętla zostaje zakończona.
Przykład:
/ Program to illustrate
// the use of simple for loop
package main
import "fmt"
// the main function
func main() {
// for loop
// This loop starts when x = 0
// executes till x<4 condition is true
// post statement is x++
for x := 0; x < 4; x++{
fmt.Printf("helloeveryone\n")
}
}
2. Pętla for jako pętla nieskończona: Usuwając wszystkie trzy wyrażenia z pętli for, pętla for może być wykorzystana jako pętla nieskończona. Gdy użytkownik nie umieści instrukcji warunku w pętli for, oznacza to, że instrukcja warunku jest prawdziwa, a pętla wchodzi w pętlę nieskończoną.
Składnia:
for
{
// (Instrukcje)
}
Przykład:
// Program to illustrate
// the use of an infinite loop
package main
import "fmt"
// the main function
func main() {
// infinite loop
for {
fmt.Printf("Helloeveryone\n")
}
}
3. Pętla while for: Pętla for może być również używana jako pętla while. Pętla ta jest powtarzana aż do spełnienia określonego warunku. Pętla kończy się, gdy wartość podanego warunku jest fałszywa.
Składnia:
for warunek {
// instrukcje
}
Przykład:
/ Program to illustrate
// for loop as while Loop
package main
import "fmt"
// the main function
func main() {
// while loop for loop executes till
// x < 3 condition is true
x:= 0
for x < 3 {
x += 2
}
fmt.Println(x)
}
4. Prosty zakres w pętli for: Zakres może być również użyty w pętli.
Składnia:
for x, y:= zakres zmiennej{
// instrukcje
}
Tutaj zmienne x i y są miejscem przechowywania wartości iteracji. Są one czasami określane jako zmienne iteracyjne. Druga zmienna, y, nie jest wymagana. Przed rozpoczęciem pętli wyrażenie zakresu jest oceniane raz.
Przykład:
// Program to illustrate
// the use of simple range loop
package main
import "fmt"
// the main function
func main() {
// Here rvariable is array
rvariable:= []string{"HEW", "Hello",
"Helloeveryoneworld"}
// x and y stores the value of rvariable
// x store index number of individual string
and
// y store individual string of the given
array
for x, y:= range rvariable {
fmt.Println(x, y)
}
}
5. Używanie pętli for dla napisów: Pętla for może iterować po punkcie kodowym łańcucha Unicode .
Składnia:
for index chr:= zakres str{
// instrukcje}
W tym przypadku indeks jest zmienną przechowującą pierwszy bajt punktu kodowego zakodowanego w UTF-8, chr jest zmienną przechowującą znaki podanego ciągu, a str jest ciągiem.
Przykład:
// Program to illustrate
// the use for loop using string
package main
import "fmt"
// the main function
func main() {
// String as range in the for loop
for x, y:= range "XxyCd" {
fmt.Printf("Index number of %U is %d\n",
y, x)
}
}
6. Dla map: Pętla for może przechodzić przez parę klucz i wartość mapy.
Składnia:
for klucz, wartość := zakres map {
// instrukcje
}
Przykład:
// Program to illustrate
// the use for loop using maps
package main
import "fmt"
// the main function
func main() {
// using the maps
mmap := map[int]string{
22:"Peeks",
33:"POP",
44:"PeeksofPeeks",
}
for key, value:= range mmap {
fmt.Println(key, value)
}
}
7. For channel: Pętla for może iterować po kolejnych danych przesyłanych w kanale, aż kanał zostanie zamknięty.
Składnia:
for item := range Chnl {
// statement(s)
}
Przykład:
// program to illustrate
// the use for loop using channel
package main
import "fmt"
// the main function
func main() {
// using the channel
chnl := make(chan int)
go func(){
chnl <- 1000
chnl <- 10000
chnl <- 100000
chnl <- 1000000
close(chnl)
}()
for x:= range chnl {
fmt.Println(x)
}
}
Ważne notatki:
o Nawiasy nie obejmują trzech instrukcji pętli for.
o Pętla wymaga nawiasów klamrowych.
o Nawias otwierający i instrukcja post powinny znajdować się w tej samej linii.
o Jeśli tablica, łańcuch, wycinek lub mapa są puste, pętla for nie zgłasza błędu i kontynuuje swój przebieg. Innymi słowy, jeśli tablica, łańcuch, wycinek lub mapa mają wartość zero, liczba iteracji pętli for wynosi zero.
Instrukcja switch Go
Instrukcja switch jest przykładem wielokierunkowej instrukcji rozgałęzienia. Oferuje efektywną metodę przenoszenia wykonania do różnych obszarów kodu w zależności od wartości wyrażenia. Język programowania Go pozwala na dwa rodzaje instrukcji switch:
o Przełącznik ekspresji
o Przełącznik typu
Wyrażenie switch
Wyrażenie switch jest analogiczne do instrukcji switch w C, C++ i Javie. Pozwala nam efektywnie kierować wykonanie do różnych obszarów kodu w oparciu o wartość wyrażenia.
Składnia:
switch optstatement; optexpression{
case expression1: Statement
case expression2: Statement
.
.
default: Statement
}
Ważne notatki:
o W przełączniku wyrażeń zarówno optstatement, jak i optexpression są wyrażeniami opcjonalnymi.
o Jeśli występują zarówno optstatement, jak i optexpression, należy je rozdzielić średnikiem (;).
o Jeśli w przełączniku nie ma wyrażenia, kompilator zakłada, że wyrażenie jest prawdziwe.
o Instrukcja opcjonalna, często znana jako optstatement, zawiera podstawowe instrukcje, takie jak deklaracje zmiennych, instrukcje przyrostu lub przypisania, wywołania funkcji itp.
o Jeśli zmienna pojawia się w instrukcji opcjonalnej, jej zakres jest ograniczony do tej instrukcji switch.
o Nie ma instrukcji break w instrukcji case i default instrukcji switch. Możemy jednak użyć instrukcji break i fallthrough, jeśli wymaga tego nasza aplikacja.
o W instrukcji switch instrukcja default jest opcjonalna.
o Sprawa może mieć wiele wartości oddzielonych przecinkiem (,).
o Jeśli przypadek nie zawiera wyrażenia, kompilator zakłada, że wyrażenie jest prawdziwe.
Pierwszy przykład:
// Program to illustrate
// the concept of Expression switch statement
package main
import "fmt"
func main() {
// the switch statement with both
// optional statement, i.e, day:=4
// and the expression, i.e, day
switch day:=5; day{
case 1:
fmt.Println("Sunday")
case 2:
fmt.Println("Monday")
case 3:
fmt.Println("Tuesday")
case 4:
fmt.Println("Wednesday")
case 5:
fmt.Println("Thursday")
case 6:
fmt.Println("Friday")
case 7:
fmt.Println("Saturday")
default:
fmt.Println("Invalid")
}
}
Drugi przykład :
// Program to illustrate
// the concept of Expression switch statement
package main
import "fmt"
func main() {
var value int = 3
// Switch statement without an
// optional statement and expression
switch {
case value == 1:
fmt.Println("Hey")
case value == 2:
fmt.Println("Hello")
case value == 3:
fmt.Println("Namstae")
default:
fmt.Println("Invalid")
}
}
Trzeci przykład:
// Program to illustrate
// the concept of Expression switch statement
package main
import "fmt"
func main() {
var value string = "four"
// Switch statement without the default
statement
// Multiple values in the case statement
switch value {
case "one":
fmt.Println("C")
case "two", "three":
fmt.Println("C#")
case "four", "five", "six":
fmt.Println("Go")
}
}
Przełącznik typu
Podczas porównywania typów stosowany jest przełącznik typu. Przypadek w tym przełączniku obejmuje typ, który będzie porównywany z typem w wyrażeniu przełącznika.
Składnia :
switch optstatement; typeswitchexpression{
case typelist 1: Statement
case typelist 2: Statement
.
.
default: Statement
}
Ważne notatki:
o Instrukcja opcjonalna, w skrócie optstatement, jest porównywalna z wyrażeniem switch.
o Sprawa może mieć wiele wartości oddzielonych przecinkiem (,).
o Instrukcje case i default w instrukcji typu switch nie zawierają instrukcji break. Możemy jednak użyć instrukcji break i fallthrough, jeśli wymaga tego nasza aplikacja.
o W instrukcji typu switch instrukcja default jest opcjonalna.
o Typeswitchexpression jest wyrażeniem, które w konsekwencji tworzy typ.
o Jeśli wyrażenie jest przypisane do zmiennej w typeswitchexpression za pomocą operatora :=, typ tej zmiennej jest określany przez typ zawarty w klauzuli case. Jeśli klauzula case zawiera dwa lub więcej typów, typem zmiennej jest typ, w którym została ona wygenerowana w typeswitchexpression.
Przykład:
// Program to illustrate
// the concept of Type switch statement
package main
import "fmt"
func main() {
var value interface{}
switch x:= value.(type) {
case bool:
fmt.Println("The value is of boolean type")
case float64:
fmt.Println("The value is of float64 type")
case int:
fmt.Println("value is of int type")
default:
fmt.Printf("value is of type: %T", x)
}
}
Tablice, wycinki i mapy
TABLICE
Tablice w języku komputerowym GoLang są podobne do tych w innych językach programowania. W oprogramowaniu może być konieczne przechowywanie zbioru danych tego samego typu, na przykład listy ocen uczniów. Tablica służy do przechowywania tego rodzaju kolekcji w programie. Tablica to sekwencja o stałej długości wykorzystywana w pamięci do przechowywania jednorodnych elementów. Ze względu na ograniczoną długość tablica nie jest tak popularna jak Slice w języku Go. Tablica może zawierać zero lub więcej niż zero elementów. Elementy tablicy są indeksowane za pomocą operatora indeksu [] z ich pozycją od zera, co oznacza, że indeksem pierwszego elementu jest tablica[0], a indeksem ostatniego elementu jest tablica[len(tablica)-1].
Tworzenie i dostęp do tablicy
Tablice są tworzone na dwa sposoby w języku programowania Go.
Używanie słowa kluczowego var
W Go za pomocą słowa kluczowego var tworzona jest tablica określonego typu z nazwą, rozmiarem i elementami.
Składnia:
Var arrayname[length]Type
lub
var arrayname[length]Typle{item1, item2, item3,
…...itemN}
Ważne notatki:
o Tablice w Go są zmienne; dlatego możemy zastosować składnię array[index] po lewej stronie przypisania, aby ustawić elementy tablicy na podany indeks.
Var nazwatablicy[indeks] = element
o Dostęp do elementów tablicy możemy uzyskać za pomocą wartości indeksu lub pętli for.
o Typ tablicy w języku programowania Go jest jednowymiarowy.
o Długość tablicy jest stała i nie można jej zmienić.
o Zduplikowane elementy mogą być przechowywane w tablicy.
Przykład
// Program to illustrate how to
// create an array using var keyword
// and accessing elements of
// the array using their index value
package main
import "fmt"
func main() {
// Creating array of string type
// Using the var keyword
var myarr[3]string
// Elements are assigned using the index
myarr[0] = "HEW"
myarr[1] = "Helloevryoneoworld"
myarr[2] = "Hello"
// Accessing elements of the array
// Using the index value
fmt.Println("Elements of Array:")
fmt.Println("Element 1: ", myarr[0])
fmt.Println("Element 2: ", myarr[1])
fmt.Println("Element 3: ", myarr[2])
}
Używanie skróconej deklaracji
Tablice w Go można również deklarować za pomocą deklaracji skróconej. Jest bardziej elastyczny niż początkowe twierdzenie.
Składnia:
arrayname:= [length]Type{item1, item2, item3,…
itemN}
Przykład:
// Program to illustrate how to create
// array using shorthand declaration
// and accessing elements of
// the array using for loop
package main
import "fmt"
func main() {
// Shorthand declaration of the array
arr:= [4]string{"hello", "hew", "Hello1431",
"Helloeveryoneworld"}
// Accessing elements of the
// array Using for loop
fmt.Println("Elements of the array:")
for x:= 0; x < 3; x++{
fmt.Println(arr[x])
}
}
Tablica wielowymiarowa
Chociaż wiemy już, że tablice są jednowymiarowe, możemy stworzyć tablicę wielowymiarową. Tablice tego samego rodzaju nazywane są tablicami wielowymiarowymi. Możemy zbudować wielowymiarową tablicę w Go, używając następującej składni:
Nazwa tablicy[Długość1][Długość2]..[DługośćN]Typ
Jak pokazano w poniższym przykładzie, możemy zbudować tablicę wielowymiarową, używając słowa kluczowego Var lub skróconej deklaracji.
Uwaga: Jeśli komórka nie zostanie zainicjowana wartością przez użytkownika w tablicy wielowymiarowej, kompilator zrobi to automatycznie. W GoLangu nie ma czegoś takiego jak niezainicjowana koncepcja.
Przykład:
// Program to illustrate
// the concept of multi-dimension array
package main
import "fmt"
func main() {
// Creating, initializing
// 2-dimensional array
// Using the shorthand declaration
// Here (,) Comma is necessary
arry:= [3][3]string{{"C", "C++", "PHP"},
{"Go", "C#", "Scala"},
{"Python", "C#", "HTML"},}
// Accessing values of
// the array Using for loop
fmt.Println("Elements of Array 1")
for a:= 0; a < 3; a++{
for b:= 0; b < 3; b++{
fmt.Println(arry[a][b])
}
}
// Creating a 2-dimensional
// array using the var keyword
// and initializing a multi
// -dimensional array using index
var arry1 [2][2] int
arry1[0][0] = 100
arry1[0][1] = 200
arry1[1][0] = 300
arry1[1][1] = 400
// Accessing values of the array
fmt.Println("Elements of the array 2")
for x:= 0; x<2; x++{
for y:= 0; y<2; y++{
fmt.Println(arry1[x][y])
}
}
}
Ważne uwagi dotyczące tablicy
1. Jeśli tablica nie została jawnie zainicjowana, domyślną wartością tej tablicy jest 0.
Przykład:
// Program to illustrate an array
package main
import "fmt"
func main() {
// Creating an array of the int type
// which stores the two elements
// Here, we do not initialize
// array so the value of array
// is zero
var myarry[2]int
fmt.Println("Elements of the Array :", myarry)
}
2. Długość tablicy można znaleźć za pomocą funkcji len(), jak pokazano w poniższym przykładzie:
// Program to illustrate how to find
// length of the array
package main
import "fmt"
func main() {
// Creating array
// Using the shorthand declaration
arry1:= [3]int{9,7,6}
arry2:= [...]int{9,7,6,4,5,3,2,4}
arry3:= [3]int{9,3,5}
// Finding length of the
// array using the len method
fmt.Println("The Length of the array 1 is:",
len(arry1))
fmt.Println("The Length of the array 2 is:",
len(arry2))
fmt.Println("The Length of the array 3 is:",
len(arry3))
}
3. Jeśli wielokropek "… pojawia się w miejscu długości tablicy, długość tablicy jest określona przez zainicjowane elementy. Jak pokazano w poniższym przykładzie:
// Program to illustrate
// the concept of ellipsis in an array
package main
import "fmt"
func main() {
// Creating an array whose size is determined
// by number of elements present in it
// Using the ellipsis
myarray:= [...]string{"HEW", "hew", "hello",
"Helloeveryoneworld", "HELLO"}
fmt.Println("Elements of array: ", myarray)
// Length of array
// is determine by
// Using the len() method
fmt.Println("Length of array is:", len(myarray))
}
4. Możemy iterować po elementach tablicy, iterując po jej zakresie. Jak pokazano w poniższym przykładzie:
// Program to illustrate
// how to iterate array
package main
import "fmt"
func main() {
// Creating an array whose size
// is represented by ellipsis
myarray:= [...]int{79, 49, 29, 20,
49, 49, 48, 39}
// Iterate array using for the loop
for y:=0; y < len(myarray); y++{
fmt.Printf("%d\n", myarray[y])
}
}
5. Tablica w Go jest typu wartościowego, a nie referencyjnego. W rezultacie, gdy tablica jest przypisywana do nowej zmiennej, wszelkie modyfikacje wprowadzone w nowej zmiennej nie mają wpływu na pierwotną tablicę. Jak pokazano w poniższym przykładzie:
// Program to illustrate value type array
package main
import "fmt"
func main() {
// Creating array whose size
// is represented by ellipsis
my_array:= [...]int{200, 300, 500, 100, 800}
fmt.Println("Original array(Before):", my_array)
// Creating new variable
// and initialize with the my_array
new_array := my_array
fmt.Println("New array(before):", new_array)
// Change value at index 0 to 500
new_array[0] = 500
fmt.Println("The New array(After):", new_array)
fmt.Println("The Original array(After):", my_array)
}
6. Jeśli typ elementu tablicy jest równoważny, to typ tablicy jest również porównywalny. W rezultacie możemy bezpośrednio porównać dwie tablice za pomocą operatora ==. Jak pokazano w poniższym przykładzie:
// Program to illustrate
// how to compare the two arrays
package main
import "fmt"
func main() {
// Arrays
arry1:= [3]int{8,7,5}
arry2:= [...]int{8,7,5}
arry3:= [3]int{8,5,3}
// Comparing arrays using == operator
fmt.Println(arry1==arry2)
fmt.Println(arry2==arry3)
fmt.Println(arry1==arry3)
// This will give error because
// type of arr1 and arr4 is mismatch
/*
arry4:= [4]int{8,7,5}
fmt.Println(arry1==arry4)
*/
}
Jak skopiować tablicę do innej tablicy w GoLang?
Tablice w języku komputerowym GoLang są podobne do tych w innych językach programowania. W programie może zaistnieć potrzeba przechowywania zbioru danych tego samego typu, np. listy ocen uczniów. Tablica służy do przechowywania tego rodzaju kolekcji w programie. Tablica to sekwencja o stałej długości wykorzystywana w pamięci do przechowywania jednorodnych elementów. GoLang nie zapewnia wbudowanej metody kopiowania jednej tablicy do drugiej. Możemy jednak zrobić klon tablicy, po prostu przypisując tablicę przez wartość lub odwołanie do nowej zmiennej. Jeśli wykonamy kopię tablicy według wartości i zmodyfikujemy wartości oryginalnej tablicy, nie będzie to odzwierciedlać zmian w kopii tej tablicy. A jeśli wykonamy kopię tablicy przez odniesienie i zmodyfikujemy wartości oryginalnej tablicy, odzwierciedli to zmiany w duplikacie tej tablicy. Jak widać na poniższych próbkach:
Składnia:
// tworzenie kopii tablicy według wartości
arry := arr1
// Tworzenie kopii tablicy przez referencję
arry := &arr1
Przyjrzyjmy się kilku przypadkom, które pomogą nam zrozumieć tę koncepcję:
Pierwszy przykład:
// Program to illustrate how
// to copy array by value
package main
import "fmt"
func main() {
// Creating, initializing an array
// Using the shorthand declaration
my_arry1 := [5]string{"C", "Go", "Java",
" Scala ", "C#"}
// Copying array into new variable
// Here, elements are passed by value
my_arry2 := my_arry1
fmt.Println("Array_1: ", my_arry1)
fmt.Println("Array_2:", my_arry2)
my_arry1[0] = "C++"
// when we copy an array
// into the another array by value
then changes made in the original
// array do not reflect in copy of that array
fmt.Println("\nThe Array_1: ", my_arry1)
fmt.Println("The Array_2: ", my_arry2)
}
Drugi przykład:
// Program to illustrate how to
// copy array by reference
package main
import "fmt"
func main() {
// Creating, initializing an array
// Using the shorthand declaration
my_arry1 := [6]int{14, 416, 47, 69, 44, 32}
// Copying array into new variable
// Here, elements are passed by reference
my_arry2 := &my_arry1
fmt.Println("Array_1: ", my_arry1)
fmt.Println("Array_2:", *my_arry2)
my_arry1[5] = 200000
// when we copy an array
// into the another array by reference
// then changes made in original
// array will reflect in
// the copy of that array
fmt.Println("\nArray_1: ", my_arry1)
fmt.Println("Array_2:", *my_arry2)
}
Jak możemy przekazać tablicę do funkcji w GoLang?
Tablice w języku komputerowym GoLang są podobne do tych w innych językach programowania. W programie może być konieczne przechowywanie zbioru danych tego samego typu, na przykład listy ocen uczniów. Tablica służy do przechowywania tego rodzaju kolekcji w programie. Tablica to sekwencja o stałej długości wykorzystywana w pamięci do przechowywania jednorodnych elementów. Możemy wysłać tablicę jako argument do funkcji w języku programowania Go. Aby przekazać tablicę jako argument do funkcji, najpierw utwórz parametr formalny o następującej składni:
Składnia:
// For the sized array
func function_name(variablename [size]type){
// Code
}
Za pomocą tej składni możemy przekazać do funkcji jedną lub więcej tablic wymiarowych. Zilustrujmy to pojęcie przykładem:
// Program to illustrate how to pass an
// array as an argument in function
package main
import "fmt"
// This function accept
// an array as argument
func myfun(a [5]int, size int) int {
var x, val, y int
for x = 0; x < size; x++ {
val += a[x]
}
y = val / size
return y
}
// the main function
func main() {
// Creating, initializing an array
var arr = [5]int{57, 29, 69, 25, 14}
var rest int
// Passing an array as an argument
rest = myfun(arr, 5)
fmt.Printf("Final result is: %d ", rest)
}
Objaśnienie: W przykładzie mamy metodę o nazwie myfun(), która pobiera tablicę jako dane wejściowe. W funkcji main przekazaliśmy arr[5] typu int do funkcji z rozmiarem tablicy, a funkcja zwróciła średnią z tablicy.
WYCINKI
Slice to struktura danych Go, która jest potężniejsza, bardziej elastyczna i wygodniejsza niż tablica. Nie można umieścić wielu komponentów w tym samym wycinku, ponieważ jest to sekwencja o zmiennej długości zawierająca elementy tego samego rodzaju. Można go porównać do tablicy, ponieważ zawiera długość i wartość indeksu. Jednak rozmiar wycinka można rozszerzyć, w przeciwieństwie do tablicy. Wewnętrznie wycinek i tablica są ze sobą połączone; wycinek jest odniesieniem do podstawowej tablicy. Zduplikowane elementy mogą być przechowywane w wycinku. W wycinku początkowy punkt indeksu to zawsze 0, a ostatni to (długość wycinka - 1).
Deklaracja wycinka
Wycinek jest określany podobnie jak tablica, ale nie podaje rozmiaru wycinka. W związku z tym może się rozszerzać i kurczyć w razie potrzeby.
Składnia:
[]T
lub
[]T{}
lub
[]T{value1, value2, value3, …...value n}
T oznacza w tym przypadku typ elementu. Jako przykład:
var myslice[]int
Komponenty wycinka
Wycinek składa się z trzech części:
o Wskaźnik: Wskaźnik jest używany do wskazania pierwszego elementu tablicy dostępnego za pośrednictwem wycinka. W tym przypadku nie jest wymagane, aby wskazany element był pierwszym elementem tablicy.
o Długość: Długość tablicy to całkowita liczba elementów w tablicy.
o Pojemność: Największy rozmiar, do którego może się rozszerzyć, jest reprezentowany przez pojemność.
Przyjrzyjmy się każdemu z tych komponentów na przykładzie:
// Program to illustrate the
// working of the slice components
package main
import "fmt"
func main() {
// Array Creation
arry := [7]string{"This", "is", "the", "example",
"of", "Go", "Programming"}
// Display array
fmt.Println("Array:", arry)
// Creating a slice
myslice := arry[1:6]
// Display the slice
fmt.Println("Slice:", myslice)
// Display the length of slice
fmt.Printf("The Length of the slice: %d",
len(myslice))
// Display the capacity of the slice
fmt.Printf("\nThe Capacity of the slice: %d",
cap(myslice))
}
Objaśnienie: W poprzednim przykładzie generujemy wycinek z tablicy. Ponieważ dolna granica wycinka jest ustawiona na jeden, wskaźnik wycinka wskazywał tutaj indeks 1. W związku z tym zaczął uzyskiwać dostęp do elementów od indeksu 1. Długość wycinka wynosi 5, co wskazuje, że w wycinku znajduje się łącznie 5 elementów, a pojemność wycinka wynosi 6, co oznacza, że może on przechowywać maksymalnie 6 elementów .
Jak możemy utworzyć i zainicjować Wycinek?
Wycinek w Go można zbudować i uruchomić w następujący sposób:
Korzystanie z literału wycinka
Użyj literału wycinka, aby wygenerować Wycinek. Konstrukcja literału wycinka jest podobna do literału tablicowego, z wyjątkiem tego, że nie można definiować rozmiaru wycinka w nawiasach kwadratowych []. Literał plastra jest przedstawiony po prawej stronie tego wyrażenia w poniższym przykładzie:
var myslice1 = []string{"Hello", "from", "Everyone"}
Uwaga: Pamiętaj, że gdy tworzymy wycinek z literałem łańcuchowym, najpierw tworzy on tablicę, a następnie zwraca do niej odwołanie do wycinka.
Przykład:
// Program to illustrate how
// to create a slice using slice literal
package main
import "fmt"
func main() {
// Creating slice using the var keyword
var myslice1 = []string{"Hello", "from",
"Everyone"}
fmt.Println("My Slice 1:", myslice1)
// Creating a slice
//using the shorthand declaration
myslice2 := []int{14, 35, 57, 49, 41, 24, 45}
fmt.Println("My Slice 2:", myslice2)
}
Korzystanie z tablicy
Ponieważ wycinek jest odniesieniem do tablicy, możemy zbudować wycinek z dostarczonej tablicy. Aby utworzyć wycinek z danej tablicy, najpierw określ dolną i górną granicę, co oznacza, że wycinek może akceptować elementy z tablicy, zaczynając od dolnej granicy i kończąc na górnej granicy. Wyklucza elementy z górnej granicy powyżej. Jak pokazano w poniższym przykładzie:
Składnia:
arrayname[low:high]
Ta składnia zwróci nowy wycinek. Należy zauważyć, że dolna granica domyślnie wynosi 0, podczas gdy górna granica jest ustawiona na całkowitą liczbę elementów w określonej tablicy.
Przykład :
// Program to illustrate how to
// create the slices from array
package main
import "fmt"
func main() {
// Array Creation
arry := [4]string{"Hello", "from",
"Developer", "HFD"}
// Creating slices from given array
var myslice1 = aryr[1:2]
myslice2 := arry[0:]
myslice3 := arry[:2]
myslice4 := arry[:]
// Display the result
fmt.Println("My Array: ", arry)
fmt.Println("My Slice 1: ", myslice1)
fmt.Println("My Slice 2: ", myslice2)
fmt.Println("My Slice 3: ", myslice3)
fmt.Println("My Slice 4: ", myslice4)
}
Korzystanie z istniejącego wycinka
Możliwe jest utworzenie nowego wycinka z dostarczonego wycinka. Aby utworzyć nowy wycinek z danego wycinka, najpierw określ dolną i górną granicę, co wskazuje, że Wycinek może pobierać komponenty z danego wycinka, zaczynając od dolnej i górnej granicy. Wyklucza elementy z górnej granicy powyżej. Jak pokazano w poniższym przykładzie:
Składnia:
slicename[low:high]
Ta składnia zwróci nowy wycinek. Należy zauważyć, że dolna granica domyślnie wynosi 0, podczas gdy górna granica jest ustawiona na całkowitą liczbę elementów w określonym wycinku.
Przykład:
// Program to illustrate how to
// create slices from slice
package main
import "fmt"
func main() {
// Creating s slice
oRignAl_slice := []int{80, 20, 50, 10,
54, 89, 70}
// Creating the slices from the given slice
var myslice1 = oRignAl_slice[1:5]
myslice2 := oRignAl_slice[0:]
myslice3 := oRignAl_slice[:6]
myslice4 := oRignAl_slice[:]
myslice5 := myslice3[2:4]
// Display result
fmt.Println("Original Slice:", oRignAl_slice)
fmt.Println("New Slice 1:", myslice1)
fmt.Println("New Slice 2:", myslice2)
fmt.Println("New Slice 3:", myslice3)
fmt.Println("New Slice 4:", myslice4)
fmt.Println("New Slice 5:", myslice5)
}
Korzystanie z funkcji make().
Możemy również użyć funkcji make() biblioteki go do wygenerowania wycinka. Ta funkcja ma trzy parametry wejściowe: typ, długość i pojemność. Wartość pojemności jest w tym przypadku opcjonalna. Zwraca wycinek, który odwołuje się do podstawowej tablicy i przypisuje podstawowej tablicy rozmiar równy podanej pojemności. W większości przypadków metoda make() tworzy pusty wycinek. W tym kontekście puste wycinki mają puste odwołanie do tablicy.
Składnia:
func make([]T, len, cap) []T
Przykład:
// Program to illustrate how to create slices
// Using the make function
package main
import "fmt"
func main() {
// Creating array of size 7 and slice this
array till 4
// and return the reference of the slice
// Using make function
var myslice1 = make([]int, 4, 7)
fmt.Printf("Slice 1 = %v, \nlength = %d, \
ncapacity = %d\n",
myslice1, len(myslice1),
cap(myslice1))
// Creating the another array of size 7
// and return the reference of slice
// Using the make function
var myslice2 = make([]int, 7)
fmt.Printf("Slice 2 = %v, \nlength = %d, \
ncapacity = %d\n",
myslice2, len(myslice2),
cap(myslice2))
}
Jak iterować po wycinku
Możliwe jest iterowanie po wycinku na następujące sposoby:
Korzystanie z pętli for
Jest to najłatwiejsza technika iteracji wycinków, jak widać w poniższym przykładzie:
// program to illustrate
// the iterating over a slice using for loop
package main
import "fmt"
func main() {
// Creating slice
myslice := []string{"This", "is", "the",
"example",
"of", "Go", "language"}
// Iterate using the for loop
for x := 0; x < len(myslice); x++ {
fmt.Println(myslice[x])
}
}
Użycie zakresu w pętli for
Użycie zakresu w pętli for pozwala nam iterować po wycinku. Indeks i wartość elementu można uzyskać za pomocą zakresu w pętli for, jak pokazano w poniższym przykładzie:
// Program to illustrate the iterating
// over a slice using range in for loop
package main
import "fmt"
func main() {
// Creating a slice
myslice := []string{"This", "is", "the", "example",
"of", "Go",
"programing"}
// Iterate the slice using range in for loop
for index, ele := range myslice {
fmt.Printf("Index = %d and element = %s\n",
index+3, ele)
}
}
Używanie pustego identyfikatora w pętli for
Jeśli nie chcemy pobierać wartości indeksu elementów w zakresie pętli for, zamiast zmiennej indeksu możemy użyć spacji (_), jak pokazano w poniższym przykładzie:
// program to illustrate the iterating over
// a slice using a range in for loop without an index
package main
import "fmt"
func main() {
// Creating slice
myslice := []string{"This", "is", "the",
"example", "of", "Go", "programing"}
// Iterate the slice
// using range in for loop without index
for _, ele := range myslice {
fmt.Printf("Element = %s\n", ele)
}
}
Ważne uwagi dotyczące wycinka
Kawałek wartości zerowej
W języku programowania Go możemy zbudować wycinek zerowy, który nie ma żadnych elementów. W rezultacie zarówno pojemność, jak i długość tego wycinka wynoszą 0. Jak widać w poniższym przykładzie, wycinek zerowy nie zawiera odwołania do tablicy:
// Program to illustrate a zero value slice
package main
import "fmt"
func main() {
// Creating zero value slice
var myslice []string
fmt.Printf("Length is = %d\n", len(myslice))
fmt.Printf("Capacity is = %d ", cap(myslice))
}
Modyfikowanie wycinków
Ponieważ Wycinek jest typem referencyjnym, może odwoływać się do podstawowej tablicy. Tak więc, jeśli zmodyfikujemy jakiekolwiek elementy w wycinku, zmiany powinny również zostać odzwierciedlone w tablicy, do której się odwołujemy. Innymi słowy, jeśli dokonamy zmian w wycinku, zmiany zostaną odzwierciedlone w tablicy, jak widać w poniższym przykładzie
// Program to illustrate
// how to modify slice
package main
import "fmt"
func main() {
// Creating zero value slice
arry := [6]int{25, 86, 97, 33, 49, 21}
slc := arry[0:4]
// Before the modifying
fmt.Println("Original_Array: ", arry)
fmt.Println("Original_Slice: ", slc)
// After the modification
slc[0] = 10
slc[1] = 100
slc[2] = 1000
fmt.Println("\nNew_Array: ", arr)
fmt.Println("New_Slice: ", slc)
}
Porównanie wycinków
W wycinku możemy użyć tylko operatora == do określenia, czy dany wycinek jest zerowy, czy nie. Jeśli spróbujemy porównać dwa wycinki za pomocą operatora ==, otrzymamy błąd, jak pokazano w poniższym przykładzie:
// Program to check if
// the slice is nil or not
package main
import "fmt"
func main() {
// creating the slices
st1 := []int{22, 38, 46}
var st2 []int
// If we try to run this commented
// code compiler will give error
/*st3:= []int{13, 55, 69}
fmt.Println(st1==st3)
*/
// Checking if the given slice is nil or not
fmt.Println(st1 == nil)
fmt.Println(st2 == nil)
}
Uwaga: Aby porównać dwa wycinki, użyj pętli for w zakresie pasującym do każdego elementu lub użyj funkcji DeepEqual.
Wielowymiarowy Wycinek
Wycinek wielowymiarowy jest podobny do tablicy wielowymiarowej, z tą różnicą, że wycinek nie zawiera rozmiaru.
Przykład:
// Program to illustrate multi-dimensional slice
package main
import "fmt"
func main() {
// Creating the multi-dimensional slice
st1 := [][]int{{13, 39},
{46, 57},
{99, 30},
{26, 76},
}
// Accessing the multi-dimensional slice
fmt.Println("Slice 1 : ", st1)
// Creating multi-dimensional slice
st2 := [][]string{
[]string{"Hello", "for"},
[]string{"everyone", "HFE"},
[]string{"hfw", "hello"},
}
// Accessing the multi-dimensional slice
fmt.Println("Slice 2 : ", st2)
}
Sortowanie Wycinka
Możemy sortować elementy w wycinku w języku programowania Go. Pakiet sort jest zawarty w standardowej bibliotece języka Go i oferuje kilka technik sortowania do sortowania wycinków int, float64 i stringów. Funkcje te zawsze sortują elementy w kolejności rosnącej dostępnej w przekroju.
Przykład:
// Program to illustrate how to sort
// elements present in the slice
package main
import (
"fmt"
"sort"
)
func main() {
// Creating the Slice
slc1 := []string{"C++", "Java", " Python ",
"Go", "Python"}
slc2 := []int{35, 87, 13, 91, 34, 41, 86, 58,
69}
fmt.Println("Before the sorting:")
fmt.Println("Slice 1: ", slc1)
fmt.Println("Slice 2: ", slc2)
// Performing sort operation on the
// slice using the sort function
sort.Strings(slc1)
sort.Ints(slc2)
fmt.Println("\nAfter sorting:")
fmt.Println("Slice 1: ", slc1)
fmt.Println("Slice 2: ", slc2)
}
Złożony literał wycinka
Wycinek i Złożony Literal to dwa słowa. Wycinek to złożony typ danych, który podobnie jak tablica zawiera elementy tego samego typu danych. Istotna różnica między tablicą a plasterkiem polega na tym, że rozmiar wycinka może zmieniać się dynamicznie, ale tablica nie. Wartości dla tablic, struktur, wycinków i map są tworzone przy użyciu literału złożonego. Za każdym razem, gdy są oceniane, tworzona jest nowa wartość. Składają się z typu literału, po którym następuje lista elementów w nawiasach klamrowych. Po przeczytaniu tego zrozumiemy, czym jest literał złożony i zdziwimy się, że już to wiemy. Przyjrzyjmy się, jak utworzyć wycinek i użyć literału złożonego:
// Program to show the slice composite literal
package main
import "fmt"
func main() {
// Slice with the composite literal
// Slice allows us to group together
// the values of same type
// here the type of values is int
st1 := []int{53, 26, 19, 84}
// displaying the values
fmt.Println(st1)
}
Rozumiemy, co oznacza termin "literał złożony". W rezultacie literały złożone są używane do przypisywania wartości lub inicjowania tablic, wycinków itp. Są one często używane do łączenia kolekcji wartości porównywalnego sortowania. W GoLang, jak sortujemy wycinek intów? Slice to struktura danych Go, która jest bardziej wszechstronna, potężniejsza i wygodniejsza niż tablica. Wycinek to sekwencja o zmiennej długości zawierająca elementy tego samego rodzaju; w tym samym wycinku nie można przechowywać wielu komponentów. Język programowania Go pozwala nam uporządkować elementy wycinka na podstawie ich typu. W rezultacie wycinek typu int jest sortowany przy użyciu poniższych funkcji. Ponieważ te funkcje są określone w pakiecie sort, musimy zaimportować pakiet sort do naszej aplikacji, aby z nich korzystać:
Ints
Ta funkcja sortuje tylko wycinek liczb całkowitych, a elementy w wycinku są sortowane w porządku rosnącym.
Składnia:
func Ints(slc []int)
W tym przypadku slc reprezentuje wycinek intów. Zilustrujmy to pojęcie przykładem:
// Program to demonstrate how
// to sort slice of ints
package main
import (
"fmt"
"sort"
)
// the main function
func main() {
// Creating, initializing slices
// Using the shorthand declaration
scl1 := []int{300, 500, 200, 300, 400, 700, 800}
scl2 := []int{-13, 267, -54, 69, 0, 22, -4}
// Displaying the slices
fmt.Println("Slices(Before):")
fmt.Println("Slice 1: ", scl1)
fmt.Println("Slice 2: ", scl2)
// Sortingslice of ints
// Using Ints function
sort.Ints (scl1)
sort.Ints (scl2)
// Displaying result
fmt.Println("\nSlices(After):")
fmt.Println("Slice 1 : ", scl1)
fmt.Println("Slice 2 : ",scl2)
}
IntsAre Sorted
Ta funkcja określa, czy dostarczony wycinek liczb typu int jest posortowany (w porządku rosnącym), czy nie. Jeśli wycinek jest w postaci posortowanej, ta funkcja zwraca wartość true; w przeciwnym razie zwraca wartość false.
Składnia:
func IntsAreSorted(scl []int) bool
W tym przypadku scl reprezentuje wycinek intów. Zilustrujmy to pojęcie przykładem:
// Program to demonstrate how to check
// whether a given slice of ints is in
// sorted the form or not
package main
import (
"fmt"
"sort"
)
// the main function
func main() {
// Creating, initializing slices
// Using the shorthand declaration
scl1 := []int{200, 100, 800, 300, 400, 500, 700}
scl2 := []int{-13, 547, -24, 97, 0, 18, -5}
// Displaying the slices
fmt.Println("Slices:")
fmt.Println("Slice 1: ", scl1)
fmt.Println("Slice 2: ", scl2)
// Checking slice is in sorted form or not
// Using IntsAreSorted function
rest1 := sort.IntsAreSorted(scl1)
rest2 := sort.IntsAreSorted(scl2)
// Displaying result
fmt.Println("\nResult:")
fmt.Println("Is Slice 1 is sorted?: ", rest1)
fmt.Println("Is Slice 2 is sorted?: ", rest2)
}
Jak można przyciąć kawałek bajtów w GoLang?
Slice to struktura danych Go, która jest bardziej wszechstronna, potężniejsza i wygodniejsza niż tablica. Wycinek to sekwencja o zmiennej długości zawierająca elementy tego samego rodzaju; w tym samym wycinku nie można przechowywać wielu komponentów. Metoda Trim() w wycinku bajtów Go pozwala nam przyciąć wszystkie początkowe i końcowe punkty kodowe zakodowane w UTF-8 z określonego wycinka. Ta metoda tworzy podwycinek oryginalnego wycinka, usuwając wszystkie początkowe i końcowe punkty kodowe zakodowane w formacie UTF-8 z podanego ciągu. Jeśli dostarczony wycinek bajtów nie zawiera wymaganego ciągu, ta metoda zwraca oryginalny wycinek bez zmian. Ponieważ jest to określone w pakiecie bytes, musimy zaimportować pakiet bytes do naszej aplikacji, aby użyć funkcji Trim.
Składnia:
func Trim(ori_slice[]byte, cut_string string) []byte
Oryginalny wycinek bajtów jest reprezentowany przez ori_slice, a cut_string reprezentuje łańcuch, który chcemy przyciąć w danym wycinku. Przeanalizujmy to pojęcie na następujących przykładach:
Pierwszy przykład:
// Program to demonstrate the concept of trim in
the slice of bytes
package main
import (
"bytes"
"fmt"
)
func main() {
// Creating, initializing
// the slice of bytes
// Using the shorthand declaration
slice_1 := []byte{'!', '!', 'H', 'e', 'e',
'l', 'o', 'o',
'o', 'r', 'W', 'o', 'r', 'l',
'd', '#', '#'}
slice_2 := []byte{'*', '*', 'G', 'r', 'a',
'p', 'e', '^', '^'}
slice_3 := []byte{'%', 'h', 'e', 'l', 'l',
'o', '%'}
// Displaying slices
fmt.Println("The Original Slice:")
fmt.Printf("Slice 1: %s", slice_1)
fmt.Printf("\nSlice 2: %s", slice_2)
fmt.Printf("\nSlice 3: %s", slice_3)
// Trimming the specified leading
// and trailing Unicodes points
// from given slice of bytes
// Using Trim function
rest1 := bytes.Trim(slice_1, "!#")
rest2 := bytes.Trim(slice_2, "*^")
rest3 := bytes.Trim(slice_3, "@")
// Display results
fmt.Printf("New Slice:\n")
fmt.Printf("\nSlice 1: %s", rest1)
fmt.Printf("\nSlice 2: %s", rest2)
fmt.Printf("\nSlice 3: %s", rest3)
}
Drugi przykład:
// Program to demonstrate the concept of trim in
the slice of bytes
package main
import (
"bytes"
"fmt"
)
func main() {
// Creating, trimming the slice of bytes
// Using the Trim function
rest1 := bytes.Trim([]byte("****Welcome to
GoWorld****"), "*")
rest2 := bytes.Trim([]byte("!!!!Learning how
to trim slice of bytes@@@@"), "!@")
rest3 := bytes.Trim([]byte("^^hello&&"), "$")
// Display results
fmt.Printf("Final Slice:\n")
fmt.Printf("\nSlice 1: %s", rest1)
fmt.Printf("\nSlice 2: %s", rest2)
fmt.Printf("\nSlice 3: %s", rest3)
}
Jak podzielić kawałek bajtów w GoLang?
Slice to struktura danych Go, która jest bardziej wszechstronna, potężniejsza i wygodniejsza niż tablica. Wycinek to sekwencja o zmiennej długości zawierająca elementy tego samego rodzaju; w tym samym wycinku nie można przechowywać wielu komponentów. Dostarczony wycinek bajtów możemy podzielić w Go za pomocą metody Split(). Ta metoda dzieli wycinek bajtów na wszystkie podwycinki podzielone przez podany separator i zwraca wycinek zawierający wszystkie te podwycinki. Ponieważ jest to określone w pakiecie bytes, musimy zaimportować pakiet bytes do naszego programu, aby użyć funkcji Split.
Składnia:
func Split(o_slice, sep []byte) [][]byte
W tym przypadku o_slice to wycinek bajtów, a sep to separator. Jeśli sep jest pusty, będzie się dzielić po każdej sekwencji UTF-8. Przeanalizujmy to pojęcie na następujących przykładach:
Pierwszy przykład:
// Program to illustrate the concept
// of splitting a slice of bytes
package main
import (
"bytes"
"fmt"
)
func main() {
// Creating, initializing the slice of bytes
// Using the shorthand declaration
slice_1 := []byte{'!', '!', 'H', 'e', 'l',
'l', 'o',
'f', 'o', 'r', 'W', 'o', 'r', 'l', 'd',
'#', '#'}
slice_2 := []byte{'G', 'r', 'a', 'p', 'e'}
slice_3 := []byte{'%', 'h', '%', 'e', '%',
'l',
'%', 'l', '%', 'o', '%'}
// Displaying slices
fmt.Println("Original Slice:")
fmt.Printf("Slice 1: %s", slice_1)
fmt.Printf("\nSlice 2: %s", slice_2)
fmt.Printf("\nSlice 3: %s", slice_3)
// Splitting slice of bytes
// Using the Split function
rest1 := bytes.Split(slice_1, []byte("eek"))
rest2 := bytes.Split(slice_2, []byte(""))
rest3 := bytes.Split(slice_3, []byte("%"))
// Display results
fmt.Printf("\n\nAfter splitting:")
fmt.Printf("\nSlice 1: %s", rest1)
fmt.Printf("\nSlice 2: %s", rest2)
fmt.Printf("\nSlice 3: %s", rest3)
}
Drugi przykład:
// Program to illustrate the concept
// of splitting a slice of bytes
package main
import (
"bytes"
"fmt"
)
func main() {
// Creating, Splitting the slice of bytes
// Using the Split function
rest1 := bytes.Split([]byte("****Welcome, to,
Tutorial****"),
[]byte(","))
rest2 := bytes.Split([]byte("Learning x how x
to x trim x a x slice of bytes"),
[]byte("x"))
rest3 := bytes.Split([]byte("Helloworld,
world"), []byte(""))
rest4 := bytes.Split([]byte(""), []byte(","))
// Display results
fmt.Printf("Final Value:\n")
fmt.Printf("\nSlice 1: %s", rest1)
fmt.Printf("\nSlice 2: %s", rest2)
fmt.Printf("\nSlice 3: %s", rest3)
fmt.Printf("\nSlice 4: %s", rest4)
}
ŁAŃCUCHY ZNAKÓW
Łańcuchy w Go różnią się od tych w innych językach, takich jak Java, C++, Python itp. Jest to ciąg znaków o zmiennej szerokości, z których każdy jest reprezentowany przez jeden lub więcej bajtów zakodowanych w UTF-8. Innymi słowy, ciągi są niezmiennym łańcuchem dowolnych bajtów (w tym bajtów o wartości zerowej) lub ciągi są fragmentem bajtów tylko do odczytu, których bajty mogą być wyrażone w tekście Unicode przy użyciu kodowania UTF-8. Ze względu na kodowanie UTF-8 ciąg GoLang może zawierać treść, która jest mieszanką wszystkich języków na świecie, nie powodując zamieszania ani nie ograniczając strony. Ciągi znaków są zazwyczaj ujęte w podwójne cudzysłowy "", jak pokazano w poniższym przykładzie:
// Program to illustrate
// how to create strings
package main
import "fmt"
func main() {
// Creating, initializing a
// variable with a string
// Using the shorthand declaration
My_value_1 := "Welcome to Home"
// Using the var keyword
var My_value_2 string
My_value_2 = "World"
// Displaying the strings
fmt.Println("String 1: ", My_value_1)
fmt.Println("String 2: ", My_value_2)
}
Literały łańcuchowe
Literały łańcuchowe są tworzone na dwa sposoby w języku programowania Go.
Korzystanie z podwójnych cudzysłowów("")
W tym przypadku literały łańcuchowe są tworzone przy użyciu podwójnych cudzysłowów (""). Ten rodzaj ciągu może zawierać znaki zmiany znaczenia, jak opisano w poniższej tabeli, ale nie może rozciągać się na kilka wierszy. Literały łańcuchowe tego rodzaju są powszechnie używane w programowaniu GoLang.
Znak ucieczki: Opis
\\ : Ukośnik wsteczny
\000 : Znak Unicode z podanym 3-cyfrowym 8-bitowym ósemkowym punktem kodowym
\' : Pojedynczy cudzysłów('). Jest dozwolone tylko wewnątrz literałów znakowych
\" : Cudzysłów("). Jest dozwolone tylko wewnątrz interpretowanych literałów łańcuchowych
\a : dzwonek ASCII
\b : Backspace ASCII
\f : Wysuw strony ASCII
\n : Przesunięcie wiersza ASCII
\r : Powrót karetki ASCII
\t : karta ASCII
\uhhhh: Znak Unicode z podanym 4-cyfrowym 16-bitowym kodem szesnastkowym Znak Unicode z podanym 8-cyfrowym 32-bitowym kodem szesnastkowym
\v : pionowa karta ASCII
\xhh : Znak Unicode z podanym 2-cyfrowym 8-bitowym szesnastkowym punktem kodowym
Używanie znaczników wstecznych (")
Literały łańcuchowe są tworzone za pomocą backticks(") i w tym kontekście są również znane jako literały surowe. Literały surowe nie pozwalają na znaki specjalne, obejmują wiele wierszy i zawierają dowolne inne znaki niż znak wsteczny. Jest powszechnie używany do tworzenia komunikatów wielowierszowych, wyrażenia regularne i HTML.
Przykład:
// Program to illustrate string literals
package main
import "fmt"
func main() {
// Creating, initializing a
// variable with string literal
// Using the double-quote
My_value_1 := "Welcome to World"
// Adding escape character
My_value_2 := "Welcome!\nWorld "
// Using backticks
My_value_3 := 'Hello!Everyone'
// Adding the escape character
// in the raw literals
My_value_4 := 'Hello!\nGeeksforGeeks'
// Displaying the strings
fmt.Println("The String 1: ", My_value_1)
fmt.Println("The String 2: ", My_value_2)
fmt.Println("The String 3: ", My_value_3)
fmt.Println("The String 4: ", My_value_4)
}
Ważne punkty dotyczące ciągów
Ciągi są niezmienne
Ciągi są niezmienne w Go. Po utworzeniu łańcucha zmiana wartości nie jest łatwa. Innymi słowy, łańcuchy są tylko do odczytu. Jeśli spróbujemy coś zmienić, kompilator zgłosi błąd.
Przykład:
// Program to illustrate
// the string are immutable
package main
import "fmt"
// the main function
func main() {
// Creating, initializing a string
// using the shorthand declaration
mystr := "Welcome to World"
fmt.Println("String:", mystr)
/* if we trying to change
the value of string
then compiler will
throw error, i.e,
cannot assign to mystr[1]
mystry[1]= 'G'
fmt.Println("String:", mystry)
*/
}
Jak iterować po łańcuchu
Użyj pętli for rang, aby przejść przez łańcuch. Ta pętla może iterować po punkcie kodu Unicode łańcucha.
Składnia:
for index, chr:= range str{
// Statement
}
W tym przypadku indeks jest zmienną przechowującą pierwszy bajt punktu kodowego zakodowanego w UTF-8, chr jest zmienną przechowującą znaki podanego ciągu, a str jest ciągiem.
Przykład:
// Program to illustrate how
// to iterate over string
// using the for range loop
package main
import "fmt"
// the main function
func main() {
// String as a range in for loop
for index, st := range "Helloeveryone" {
fmt.Printf("Index number of %c is
%d\n", st, index)
}
}
Jak uzyskać dostęp do pojedynczego bajtu łańcucha
Możemy uzyskać dostęp do każdego bajtu podanego tekstu, ponieważ jest to ciąg bajtów.
Przykład:
// Program to illustrate how to
// access bytes of the string
package main
import "fmt"
// Main function
func main() {
// Creating, initializing a string
str := "Welcome to World"
// Accessing the bytes of the given string
for x := 0; x < len(str); x++ {
fmt.Printf("\nCharacter = %c Bytes = %v",
str, str)
}
}
Jak zrobić ciąg znaków z kawałka bajtów
W Go możemy utworzyć ciąg znaków z kawałka bajtów.
Przykład:
package main
import (
"fmt"
"reflect"
"strings"
)
func main() {
stry1 := []string{"Drum", "of", "India", "On",
"Dec"}
fmt.Println(stry1)
fmt.Println(reflect.TypeOf(stry1))
stry2 := strings.Join(stry1, " ")
fmt.Println(stry2)
fmt.Println(reflect.TypeOf(stry2))
stry3 := strings.Join(stry1, ", ")
fmt.Println(stry3)
fmt.Println(reflect.TypeOf(stry3))
}
Jak możemy określić długość łańcucha w GoLang?
Długość łańcucha znaków w GoLangu możemy znaleźć za pomocą dwóch funkcji: len() i RuneCountInString(). Pakiet UTF-8 zawiera metodę RuneCountInString(), która zwraca całkowitą runę w łańcuchu. A metoda len() zwraca długość łańcucha w bajtach.
Przykład:
// Program to illustrate how to
// find the length of the string
package main
import (
"fmt"
"unicode/utf8"
)
// the main function
func main() {
// Creating, initializing a string
// using the shorthand declaration
mystr := "Welcome to Everyone???"
// Finding length of the string
// Using len() function
length1 := len(mystr)
// Using the RuneCountInString() function
length2 := utf8.RuneCountInString(mystr)
// Displaying length of the string
fmt.Println("string:", mystr)
fmt.Println("Length 1:", length1)
fmt.Println("Length 2:", length2)
}
Jak przycinamy string w GoLang?
Łańcuchy w Go różnią się od tych w innych językach, takich jak Java, C++, Python itp. Jest to ciąg znaków o zmiennej szerokości, z których każdy jest reprezentowany przez jeden lub więcej bajtów zakodowanych w UTF-8. Możemy przycinać ciąg na różne sposoby, korzystając z poniższych metod. Te funkcje są określone w pakiecie strings; dlatego musimy zaimportować pakiet strings do Twojej aplikacji, aby z nich korzystać.
Trim
Ta funkcja przycina tekst, usuwając wszystkie początkowe i końcowe punkty kodu Unicode podane w tej funkcji.
Składnia:
func Trim(str string, cutstr string) string
W tym przypadku str reprezentuje bieżący łańcuch, a cutstr reprezentuje elementy w określonym łańcuchu, które chcemy usunąć.
Przykład:
// Program to illustrate
// how to trim string
package main
import (
"fmt"
"strings"
)
// the main method
func main() {
// Creating, initializing string
// Using the shorthand declaration
stry1 := "!!Welcome to Everyone !!"
stry2 := "@@This is the example of Golang$$"
// Displaying strings
fmt.Println("Strings before the trimming:")
fmt.Println("String 1: ", stry1)
fmt.Println("String 2:", stry2)
// Trimming given strings
// Using Trim() function
rest1 := strings.Trim(stry1, "!")
rest2 := strings.Trim(stry2, "@$")
// Displaying results
fmt.Println("\nStrings after the trimming:")
fmt.Println("Result 1: ", rest1)
fmt.Println("Result 2:", rest2)
}
TrimLeft
Funkcja TrimLeft służy do przycinania punktów kodu Unicode łańcucha po lewej stronie (podanej w funkcji).
Składnia:
func TrimLeft(str string, cutstr string) string
W tym przypadku str reprezentuje bieżący łańcuch, a cutstr reprezentuje elementy po lewej stronie określonego ciągu, które chcemy przyciąć.
Przykład:
// Program to illustrate how to
// trim the left-hand side elements
// from string
package mainv
import (
"fmt"
"strings"
)
// the main method
func main() {
// Creating, initializing string
// Using the shorthand declaration
stry1 := "!!Welcome to Everyone **"
stry2 := "@@This is the example of Golang$$"
// Displaying the strings
fmt.Println("Strings before trimming:")
fmt.Println("String 1: ", stry1)
fmt.Println("String 2:", stry2)
// Trimming the given strings
// Using the TrimLeft() function
rest1 := strings.TrimLeft(str1, "!*")
rest2 := strings.TrimLeft(str2, "@")
// Displaying results
fmt.Println("\nStrings after trimming:")
fmt.Println("Result 1: ", rest1)
fmt.Println("Result 2:", rest2)
}
TrimRight
Ta funkcja przycina prawą stronę łańcucha (podaną w funkcji)
Punkty kodu Unicode.
Składnia:
func TrimRight(str string, cutstr string) string
W tym przypadku str reprezentuje bieżący łańcuch, a cutstr reprezentuje komponenty po prawej stronie określonego ciągu, które chcemy przyciąć.
Przykład:
// Program to illustrate how to
// trim the right-hand side elements
// from string
package main
import (
"fmt"
"strings"
)
// the main method
func main() {
// Creating, initializing the
// string using the shorthand declaration
stry1 := "!!Welcome to Everyone **"
stry2 := "@@This is the example of Golang$$"
// Displaying the strings
fmt.Println("Strings before the trimming:")
fmt.Println("String 1: ", stry1)
fmt.Println("String 2:", stry2)
// Trimming given strings
// Using the TrimRight() function
rest1 := strings.TrimRight(stry1, "!*")
rest2 := strings.TrimRight(stry2, "$")
// Displaying results
fmt.Println("\nStrings after trimming:")
fmt.Println("Result 1: ", rest1)
fmt.Println("Result 2:", rest2)
}
TrimSpace
Ta metoda usuwa wszystkie wiodące i końcowe spacje z podanego ciągu.
Składnia:
func TrimSpace(str string) string
Przykład:
// Program to illustrate how to
// trim the white space from string
package main
import (
"fmt"
"strings"
)
// the main method
func main() {
// Creating, initializing string
// Using the shorthand declaration
stry1 := " **Welcome to Everyone** "
stry2 := " ##This is the example of Golang## "
// Displaying the strings
fmt.Println("Strings before the trimming:")
fmt.Println(stry1, stry2)
// Trimming the white space from given strings
// Using TrimSpace() function
rest1 := strings.TrimSpace(stry1)
rest2 := strings.TrimSpace(stry2)
// Displaying results
fmt.Println("\nStrings after the trimming:")
fmt.Println(rest1, rest2)
}
TrimSuffix
Ta metoda usuwa końcowy sufiks ciągu. Jeśli podany ciąg nie zawiera określonego ciągu sufiksu, ta metoda zwraca oryginalny ciąg w niezmienionej postaci.
Składnia:
func TrimSuffix(str, suffstr string) string
Oryginalny ciąg jest reprezentowany przez str, podczas gdy ciąg sufiksu jest reprezentowany przez suffstr.
Przykład:
// Program to illustrate how to
// trim suffix string from
// the given string
package main
import (
"fmt"
"strings"
)
// the main method
func main() {
// Creating, initializing string
// Using the shorthand declaration
stry1 := "Welcome, Everyone"
stry2 := "This is the, example of Golang"
// Displaying the strings
fmt.Println("Strings before the trimming:")
fmt.Println("String 1: ", stry1)
fmt.Println("String 2:", stry2)
// Trimming the suffix string from given strings
// Using the TrimSuffix() function
rest1 := strings.TrimSuffix(str1, "Helloworld")
rest2 := strings.TrimSuffix(str2, "Helloo")
// Displaying results
fmt.Println("\nStrings after the trimming:")
fmt.Println("Result 1: ", rest1)
fmt.Println("Result 2:", rest2)
}
TrimPrefix
Ta metoda usuwa wiodący przedrostek ciągu. Jeśli podany ciąg nie zawiera żądanego ciągu prefiksu, ta metoda zwraca oryginalny ciąg w niezmienionej postaci.
Składnia:
func TrimPrefix(str, suffstr string) string
Oryginalny ciąg jest reprezentowany przez str, podczas gdy ciąg przedrostka jest reprezentowany przez suffstr.
Przykład:
// Program to illustrate how to
// trim prefix string from
// the given string
package main
import (
"fmt"
"strings"
)
// the Main method
func main() {
// Creating, initializing string
// Using the shorthand declaration
stry1 := "Welcome, Everyone"
stry2 := "This is the, example of Golang"
// Displaying the strings
fmt.Println("Strings before the trimming:")
fmt.Println("String 1: ", stry1)
fmt.Println("String 2: ", stry2)
// Trimming the prefix string from given
strings
// Using the TrimPrefix() function
rest1 := strings.TrimPrefix(str1, "Hello")
rest2 := strings.TrimPrefix(str2, "World")
// Displaying results
fmt.Println("\nStrings after the trimming:")
fmt.Println("Result 1: ", rest1)
fmt.Println("Result 2: ", rest2)
}
Jak dzielimy łańcuch w GoLang?
Łańcuchy w Go różnią się od tych w innych językach, takich jak Java, C++, Python itp. Jest to ciąg znaków o zmiennej szerokości, z których każdy jest reprezentowany przez jeden lub więcej bajtów zakodowanych w UTF-8. Za pomocą poniższych funkcji możemy podzielić ciąg na wycinek w ciągach Go. Ponieważ te funkcje są określone w pakiecie strings, musimy zaimportować pakiet strings do naszego programu, aby z nich korzystać:
Split
Ta funkcja dzieli łańcuch na wszystkie podłańcuchy oddzielone określonym separatorem i zwraca wycinek zawierający te podłańcuchy.
Składnia:
func Split(str, sep string) []string
Używany jest tutaj łańcuch str i używany jest separator sep. Jeśli str nie zawiera podanego sep, a sep nie jest puste, zwróci wycinek o długości 1, który zawiera wyłącznie str. Jeśli parametr sep pozostanie pusty, będzie dzielić po każdej sekwencji UTF-8. Alternatywnie, jeśli zarówno str, jak i sep są puste, utworzy pusty wycinek.
Przykład:
// Program to demonstrate how to split a string
package main
import (
"fmt"
"strings"
)
// the main function
func main() {
// Creating, initializing the strings
stry1 := "Welcome, to the, our channel,
Helloeveryone"
stry2 := "My dog name is Dollar"
stry3 := "I like to play Ludo"
// Displaying the strings
fmt.Println("String 1: ", stry1)
fmt.Println("String 2: ", stry2)
fmt.Println("String 3: ", stry3)
// Splitting given strings
// Using the Split() function
rest1 := strings.Split(stry1, ",")
rest2 := strings.Split(stry2, "")
rest3 := strings.Split(stry3, "!")
rest4 := strings.Split("", "Helloeveryone,
hello")
// Displaying result
fmt.Println("\nResult 1: ", rest1)
fmt.Println("Result 2: ", rest2)
fmt.Println("Result 3: ", rest3)
fmt.Println("Result 4: ", rest4)
}
SplitAfter
Dzieli ciąg na wszystkie podciągi po każdym wystąpieniu podanego separatora i zwraca wycinek zawierający te podciągi.
Składnia:
func SplitAfter(str, sep string) []string
Używany jest tutaj łańcuch str i używany jest separator sep. Jeśli str nie zawiera podanego sep, a sep nie jest puste, zwróci wycinek o długości 1, który zawiera wyłącznie str. Jeśli parametr sep pozostanie pusty, będzie dzielić po każdej sekwencji UTF-8. Alternatywnie, jeśli zarówno str, jak i sep są puste, utworzy pusty wycinek.
Przykład:
// Program to demonstrate how to split a string
package main
import (
"fmt"
"strings"
)
// the main function
func main() {
// Creating, initializing the strings
stry1 := "Welcome, to the, online session,
Helloeveryone"
stry2 := "My cat name is puffi"
stry3 := "I like to play chess"
// Displaying the strings
fmt.Println("String 1: ", stry1)
fmt.Println("String 2: ", stry2)
fmt.Println("String 3: ", stry3)
// Splitting given strings
// Using the SplitAfter() function
rest1 := strings.SplitAfter(str1, ",")
rest2 := strings.SplitAfter(str2, "")
rest3 := strings.SplitAfter(str3, "!")
rest4 := strings.SplitAfter("",
"Helloeveryone, Hello")
// Displaying result
fmt.Println("\nResult 1: ", rest1)
fmt.Println("Result 2: ", rest2)
fmt.Println("Result 3: ", rest3)
fmt.Println("Result 4: ", rest4)
}
SplitAfterN
Dzieli ciąg na wszystkie podciągi po każdym użyciu podanego separatora i zwraca wycinek zawierający te podciągi.
Składnia:
func SplitAfterN(str, sep string, m int) []string
W tym przypadku str to łańcuch, sep to separator, a m to liczba podłańcuchów do zwrócenia. Jeśli m>0, zwróci co najwyżej m podłańcuchów, przy czym końcowy podłańcuch nie zostanie podzielony. Jeśli m == zero, zwróci zero. Jeśli m<0, zwraca wszystkie podłańcuchy.
Przykład:
// Program to demonstrate how to split a string
package main
import (
"fmt"
"strings"
)
// the main function
func main() {
// Creating, initializing the strings
stry1 := "Welcome, to the, online session,
Helloeveryone"
stry2 := "My cat name is puffi"
stry3 := "I like to play chess"
// Displaying strings
fmt.Println("String 1: ", stry1)
fmt.Println("String 2: ", stry2)
fmt.Println("String 3: ", stry3)
// Splitting given strings
// Using SplitAfterN() function
rest1 := strings.SplitAfterN(stry1, ",", 2)
rest2 := strings.SplitAfterN(stry2, "", 4)
rest3 := strings.SplitAfterN(stry3, "!", 1)
rest4 := strings.SplitAfterN("",
"Helloeveryone, hello", 3)
// Displaying result
fmt.Println("\nResult 1: ", rest1)
fmt.Println("Result 2: ", rest2)
fmt.Println("Result 3: ", rest3)
fmt.Println("Result 4: ", rest4)
}
W GoLang istnieje kilka sposobów porównywania ciągów znaków. Łańcuch w Go jest niezmiennym łańcuchem dowolnych bajtów zakodowanych przy użyciu kodowania UTF-8. Mamy dwie możliwości porównywania łańcuchów znaków:
Korzystanie z operatorów porównania
Łańcuchy Go umożliwiają operatory porównania, takie jak ==, !=, >=, <=, <, >. Operatory == i != służą do określenia, czy podane łańcuchy są równe, natomiast operatory >=, <=, <, > określają kolejność leksykalną. Wyniki tych operatorów są typu Boolean, co oznacza, że warunek jest spełniony. Zwróci wartość true; w przeciwnym razie fałszywe.
Pierwszy przykład:
// Program to illustrate the concept
// of == and != operator with the strings
package main
import "fmt"
// the main function
func main() {
// Creating, initializing strings
// using the shorthand declaration
stry1 := "Hello"
stry2 := "Helo"
stry3 := "Helloeveryone"
stry4 := "Hello"
// Checking string are equal
// or not using == operator
res1 := str1 == str2
res2 := str2 == str3
res3 := str3 == str4
res4 := str1 == str4
fmt.Println("Result 1: ", res1)
fmt.Println("Result 2: ", res2)
fmt.Println("Result 3: ", res3)
fmt.Println("Result 4: ", res4)
// Checking the string are not equal
// using != operator
res5 := str1 != str2
res6 := str2 != str3
res7 := str3 != str4
res8 := str1 != str4
fmt.Println("\nResult 5: ", res5)
fmt.Println("Result 6: ", res6)
fmt.Println("Result 7: ", res7)
fmt.Println("Result 8: ", res8)
}
Drugi przykład:
// Program to illustrate concept
// of comparison operator with the strings
package main
import "fmt"
// the main function
func main() {
// Creating, initializing
// slice of string using
// the shorthand declaration
myslice := []string{"Hello", "Hello",
"hfw", "HFW", "from"}
fmt.Println("Slice: ", myslice)
// Using the comparison operator
result1 := "HFW" > "Hello"
fmt.Println("Result 1: ", result1)
result2 := "HFW" < "hello"
fmt.Println("Result 2: ", result2)
result3 := "Hello" >= "from"
fmt.Println("Result 3: ", result3)
result4 := "Hello" <= "from"
fmt.Println("Result 4: ", result4)
result5 := "Hello" == "Hello"
fmt.Println("Result 5: ", result5)
result6 := "Hello" != "from"
fmt.Println("Result 6: ", result6)
}
Korzystanie z metody Compare().
Możemy również porównać dwa ciągi znaków za pomocą wbudowanej funkcji pakietu strings Compare(). Po leksykograficznym porównaniu dwóch łańcuchów ta metoda generuje wartość całkowitą. Zwracane wartości są następujące:
Return 0, if stry1 == stry2.
Return 1, if stry1 > stry2.
Return -1, if stry1 < stry2.
Składnia:
func Compare(stry1, stry2 string) int
Przykład:
// Program to illustrate how to compare
// the string using compare() function
package main
import (
"fmt"
"strings"
)
func main() {
// Comparing string using the Compare function
fmt.Println(strings.Compare("hfw", "Hello"))
fmt.Println(strings.Compare("Helloeveryone",
"Hello"))
fmt.Println(strings.Compare("Hello", " HFW"))
fmt.Println(strings.Compare("HelLo", "HelLo"))
}
MAPY
Mapa to silna, pomysłowa i elastyczna struktura danych w języku programowania Go. Mapy w języku GoLang to zbiór par klucz-wartość, które nie są uporządkowane. Jest powszechnie używany, ponieważ umożliwia szybkie wyszukiwanie i wartości, które można pobrać, zaktualizować lub usunąć za pomocą klawiszy.
o Jest to odwołanie do tablicy skrótów.
o Przejście jest niedrogie ze względu na typ referencyjny; na przykład na procesorze 64-bitowym wymaga 8 bajtów, podczas gdy na komputerze 32-bitowym zajmuje 4 bajty.
o Klucz na mapie musi być unikalny i zawsze typu, który jest porównywany za pomocą operatora == lub typu, który obsługuje operator !=. W rezultacie większość wbudowanych typów, takich jak int, float64, rune, string, podobna tablica i struktura, wskaźnik itd., może być używana jako klucze. Typy danych, takie jak wycinki i nieporównywalne tablice i struktury oraz niestandardowe typy danych, które nie są porównywalne, nie są używane jako klucze map.
o Wartości w mapach nie są unikalne jak klucze i mogą być dowolnego typu, np. int, float64, string, rune, pointer, typ referencyjny, typ mapy itp.
o Klucze i wartości muszą być tego samego typu; różne klucze i wartości w tych samych mapach są niedozwolone. Jednak typ klucza i wartości typu mogą się różnić.
o Tablica mieszająca, mapa mieszająca, mapa nieuporządkowana, słownik lub tablica asocjacyjna to nazwy innych map.
o Możemy dodać wartość do mapy dopiero po jej zainicjowaniu. Jeśli dodamy wartość do niezainicjowanej mapy, kompilator zgłosi błąd.
Jak tworzymy i inicjalizujemy mapy?
Mapy w języku programowania Go można tworzyć i inicjalizować na dwa sposoby:
Prosty
Możemy użyć tego sposobu do skonstruowania i zainicjowania mapy bez użycia funkcji make():
1. Tworzenie mapy: Używając następującej składni, możemy łatwo stworzyć mapę:
// Empty map
map[KeyType]ValueType{}
// Map with the keyvalue pair
map[KeyType]ValueType{key1: value1, &helip;, keyN:
valueN}
Przykład:
var mymap map[int]string
Wartość zerowa mapy w mapach jest zerowa, a mapa zerowa nie zawiera żadnych kluczy. Jeśli wstawimy parę klucz-wartość do mapy nil, kompilator zgłosi błąd wykonania.
2. Używanie literałów map do inicjalizacji mapy: Literały map są najprostszym sposobem wypełnienia mapy danymi; oddziel parę klucz-wartość dwukropkiem, a ostatni końcowy dwukropek jest wymagany; w przeciwnym razie kompilator wygeneruje błąd.
Przykład:
// Program to illustrate how to
// create, initialize maps
package main
import "fmt"
func main() {
// Creating, initializing empty map
// Using the var keyword
var map_1 map[int]int
// Checking if map is nil or not
if map_1 == nil {
fmt.Println("True")
} else {
fmt.Println("False")
}
// Creating, initializing a map
// Using the shorthand declaration and
// using the map literals
map_2 := map[int]string{
90: "Duck",
91: "Cow",
92: "Cat",
93: "Bird",
94: "Boat",
}
fmt.Println("Map-2: ", map_2)
}
Korzystanie z funkcji make().
Możemy również utworzyć mapę za pomocą funkcji make(). Ta funkcja jest funkcją wbudowaną iw tej metodzie musimy przekazać typ mapy i zwrócić zainicjowaną mapę.
Składnia:
make(map[KeyType]ValueType, initial_Capacity)
make(map[KeyType]ValueType)
Przykład:
// Program to illustrate how to
// create, initialize a map
// Using the make() function
package main
import "fmt"
func main() {
// Creating map
// Using the make() function
var Mymap = make(map[float64]string)
fmt.Println(Mymap)
// As we know that make() function always
returns a map which is initialized
// we can add values in it
Mymap[1.3] = "Ridhi"
Mymap[1.5] = "Sunita"
fmt.Println(Mymap)
}
Ważne uwagi
Jak iterujemy po mapie?
Możemy użyć pętli for do iteracji po mapie. Ponieważ mapa jest zbiorem nieuporządkowanym, wartość tej pętli może się różnić.
Przykład:
// Program to illustrate how
// to iterate map using for rang loop
package main
import "fmt"
// the main function
func main() {
// Creating, initializing a map
m_a_p := map[int]string{
90: "Duck",
91: "Cow",
92: "Cat",
93: "Bird",
94: "Dog",
}
// Iterating the map using for rang loop
for id, pet := range m_a_p {
fmt.Println(id, pet)
}
}
Jak dodać pary klucz-wartość do mapy
W mapach możemy dodawać pary klucz-wartość do zainicjowanej mapy, używając następującej składni:
map-name[key]=value
Jeśli spróbujemy dodać klucz, który już istnieje na mapie, po prostu zastąpi on lub zaktualizuje wartość tego klucza nową wartością.
Przykład:
// Program to illustrate how to add
key-value pair in the map using make() function
package main
import "fmt"
// the main function
func main() {
// Creating, initializing a map
m_a_p := map[int]string{
90: "Duck",
91: "Cow",
92: "Dog",
93: "Cat",
94: "Rabbit",
}
fmt.Println("Original map: ", m_a_p)
// Adding the new key-value pairs in the map
m_a_p[95] = "Parrot"
m_a_p[96] = "Crow"
fmt.Println("Map after adding the new keyvalue
pair:\n", m_a_p)
// Updating the values of map
m_a_p[91] = "PIG"
m_a_p[93] = "MONKEY"
fmt.Println("\nMap after updating the values
of map:\n", m_a_p)
}
Jak odzyskać wartość powiązaną z kluczem na mapie
Na mapach użyj następującej składni, aby uzyskać wartość za pomocą klucza:
nazwa_mapy [klucz]
Jeśli klucz nie istnieje w danej mapie, zwróci wartość zerową, czyli zero. A jeśli klucz zostanie znaleziony na danej mapie, zwróci wartość powiązaną z tym kluczem.
Przykład:
// Program to illustrate how to
// retrieve the value of key
package main
import "fmt"
// the ain function
func main() {
// Creating, initializing a map
m_a_p := map[int]string{
90: "Duck",
91: "Cow",
92: "Cat",
93: "Dog",
94: "Rabbit",
}
fmt.Println("Original map: ", m_a_p)
// Retrieving values with help of keys
value_1 := m_a_p[91]
value_2 := m_a_p[92]
fmt.Println("Value of key[91]: ", value_1)
fmt.Println("Value of key[92]: ", value_2)
}
Jak sprawdzić, czy klucz jest obecny na mapie
W mapach możemy użyć następującej składni, aby określić, czy dany klucz istnieje, czy nie:
Składnia:
// With the value
// It will give the value, check the result
value, checkvariablename:= mapname[key]
lub
// Without the value using the blank identifier
// It will only give check result
_, checkvariablename:= mapname[key]
Jeśli wartość zmiennej checkvariablename jest prawdziwa, klucz istnieje w podanej mapie; jeśli wartość checkvariablename jest false, klucz nie istnieje w danej mapie.
Przykład:
// Program to illustrate how to
// check key is available or not
package main
import "fmt"
// the main function
func main() {
// Creating. initializing a map
m_a_p := map[int]string{
90: "Cow",
91: "Cat",
92: "Duck",
93: "Dog",
94: "Rabbit",
}
fmt.Println("Original map: ", m_a_p)
// Checking key is available
or not in the m_a_p map
pet_name, ok := m_a_p[90]
fmt.Println("\nThe Key present or not:", ok)
fmt.Println("The Value:", pet_name)
// Using the blank identifier
_, ok1 := m_a_p[92]
fmt.Println("\nThe Key present or not:", ok1)
}
Jak usunąć klucz z mapy
Metoda delete() w mapach pozwala nam usunąć klucz istniejący w mapie. Jest to wbudowana funkcja, która nie zwraca żadnej wartości i nic nie robi, jeśli klucz nie istnieje w określonej mapie. Wystarczy przekazać do tej metody mapę i klucz, który chcemy usunąć z mapy.
Składnia:
delete(mapname, key)
Przykład:
// Program to illustrate how to delete key
package main
import "fmt"
// the main function
func main() {
// Creating, initializing a map
m_a_p := map[int]string{
90: "Duck",
91: "Cow",
92: "Cat",
93: "Dog",
94: "Rabbit",
}
fmt.Println("Original map: ", m_a_p)
// Deleting keys
// Using the delete function
delete(m_a_p, 91)
delete(m_a_p, 92)
fmt.Println("Map after deletion: ", m_a_p)
}
Modyfikacja mapy
Jak wszyscy wiemy, mapy mają charakter referencyjny. W rezultacie, kiedy przypisujemy istniejącą mapę do nowej zmiennej, obie mapy odnoszą się do tej samej podstawowej struktury danych. W rezultacie, gdy zaktualizujemy jedną mapę, znajdzie to odzwierciedlenie w innej.
Przykład:
// Program to illustrate the
// modification concept in map
package main
import "fmt"
// the main function
func main() {
// Creating, initializing a map
m_a_p := map[int]string{
90: "Duck",
91: "Cow",
92: "Cat",
93: "Duck",
94: "Rabbit",
}
fmt.Println("Original map: ", m_a_p)
// Assigned map into a new variable
new_map := m_a_p
// Perform the modification in new_map
new_map[96] = "Monkey"
new_map[98] = "Donkey"
// Display after modification
fmt.Println("The New map: ", new_map)
fmt.Println("\nModification done in old
map:\n", m_a_p)
}
Funkcje i rekurencja
Przejdź do FUNKCJE JĘZYKOWE
Funkcje to często bloki kodu lub instrukcje w programie, które umożliwiają użytkownikowi ponowne użycie tego samego kodu, oszczędzając pamięć, oszczędzając czas i, co najważniejsze, poprawiając czytelność kodu. Funkcja jest w istocie zbiorem instrukcji, które wykonują dane zadanie i dostarczają wynik wywołującemu. Funkcja może również wykonać określone zadanie bez zwracania żadnych wyników.
Deklaracja funkcji
Deklaracja funkcji jest metodą konstruowania funkcji.
Składnia:
func nazwa-funkcji(Parameterlist)(Returntype){
// ciało funkcji
}
W deklaracji funkcji znajdują się:
o func: Jest to słowo kluczowe w języku programowania Go używane do definiowania funkcji.
o nazwa-funkcji: To jest nazwa funkcji.
o Lista parametrów: Określa nazwę i typ argumentów funkcji.
o Returntype: Ten parametr jest opcjonalny i zawiera typy wartości zwracanych przez funkcję. Jeśli zamierzamy użyć zwracanego typu w naszej funkcji będziemy musieli dołączyć instrukcję return
Wywoływanie funkcji
Kiedy użytkownik chce wykonać funkcję, wywołuje ją lub wywołuje. Aby skorzystać z możliwości funkcji, należy ją wywołać. Jak pokazano w poniższym przykładzie, mamy funkcję o nazwie area() z dwoma parametrami. Teraz nazywamy tę funkcję po imieniu w funkcji main, tj. area(13, 11) z dwoma parametrami.
Przykład:
// Program to illustrate
// the use of function
package main
import "fmt"
// area() is used to find
// area of rectangle
// area() function two parameters,
// i.e, length and width
func area(length, width int)int{
arr := length* width
return arr
}
// the main function
func main() {
// Display area of the rectangle
// with the method calling
fmt.Printf("Area of rectangle is : %d",
area(13, 11))
}
Argumenty funkcji
Argumenty dostarczane do funkcji nazywane są w Go parametrami rzeczywistymi, podczas gdy parametry odbierane przez funkcję nazywane są parametrami formalnymi.
Uwaga: język Go domyślnie używa techniki call by value aby przekazać parametry w funkcji.
Język programowania Go udostępnia dwie metody przekazywania parametrów do naszej funkcji.
Wywołanie według wartości
W ten sposób przekazywania parametrów wartości parametrów rzeczywistych są przekazywane do parametrów formalnych funkcji, a dwa rodzaje parametrów są przechowywane w różnych miejscach pamięci. W rezultacie wszelkie zmiany dokonane w obrębie funkcji nie znajdują odzwierciedlenia w rzeczywistych argumentach wywołujących.
Przykład:
// Program to illustrate
// the concept of call by value
package main
import "fmt"
// function which swap the values
func swap(x, y int)int{
var o int
o= x
x=y
y=o
return o
}
// the main function
func main() {
var a int = 20
var b int = 30
fmt.Printf("a = %d and b = %d", a, b)
// call by values
swap(a, b)
fmt.Printf("\n a = %d and b = %d",a, b)
}
Wywołanie przez referencje
Ponieważ zarówno parametry rzeczywiste, jak i parametry formalne odnoszą się do identycznych lokalizacji, wszelkie zmiany dokonane w ramach funkcji mają odzwierciedlenie w rzeczywistych parametrach wywołującego.
Przykład:
// Program to illustrate
// the concept of call by reference
package main
import "fmt"
// function which swap the values
func swap(x, y *int)int{
var o int
o = *x
*x = *y
*y = o
return o
}
// the main function
func main() {
var a int = 20
var b int = 10
fmt.Printf("a = %d and b = %d", a, b)
// call by reference
swap(&a, &b)
fmt.Printf("\n a = %d and b = %d", a, b)
}
FUNKCJA ZWRACAJĄCA WIELE WARTOŚCI
Instrukcja return w języku programowania Go pozwala nam zwrócić wiele wartości z funkcji. Innymi słowy, pojedyncza instrukcja return w funkcji może zwrócić wiele wartości. Zwracane wartości są tego samego typu, co parametry podane na liście parametrów.
Składnia:
func functionname(parameterlist)(returntypelist){
// code…
}
Przykład:// Program to illustrate how a
// function return the multiple values
package main
import "fmt"
// myfunc return 3 values of int type
func myfunc(x, y int)(int, int, int ){
return x - y, x * y, x + y
}
// the main Method
func main() {
// return values are assigned into different
variables
var myvar1, myvar2, myvar3 = myfunc(4, 2)
// Display-values
fmt.Printf("The Result is: %d", myvar1 )
fmt.Printf("\nThe Result is: %d", myvar2)
fmt.Printf("\nThe Result is: %d", myvar3)
}
Nadawanie nazw zwracanym wartościom
Zwracanym wartościom w języku programowania Go można nadać nazwy. Takich nazw zmiennych możemy używać również w naszym kodzie. Nie jest wymagane dołączanie instrukcji return do tych identyfikatorów, ponieważ kompilator Go rozpozna, że te zmienne muszą zostać odesłane. Nagi powrót to nazwa nadana tej formie zwrotu. Zastosowanie samego zwrotu minimalizuje redundancję w naszym programie.
Składnia:
func functionname(para1, para2 int)(name1 int, name2 int){
// code
}
name1 i name2 to nazwy zwracanych wartości, podczas gdy para1 i para2 to argumenty funkcji.
Przykład:
// illustrate how to give names to return values
package main
import "fmt"
// myfunc return 2 values of the int type
// here, return value name
// is rectangle & square
func myfunc(x, y int)( rectangle int, square int )
{
rectangle = x*y
square = x*x
return
}
func main() {
// The return values are assigned into the two
different variables
var area1, area2 = myfunc(4, 8)
// Display the values
fmt.Printf("Area of the rectangle is: %d",
area1 )
fmt.Printf("\nThe Area of the square is: %d",
area2)
}
FUNKCJE ZMIENNE
Funkcja wariadyczna to taka, która jest wywoływana ze zmienną liczbą parametrów. Innymi słowy, funkcja variadic akceptuje zero lub więcej danych wejściowych od użytkownika. fmt. Printf jest przykładem funkcji wariadycznej; wymaga jednego stałego argumentu na początku i może zaakceptować dowolną liczbę argumentów później.
Ważne notatki:
o Ostatni typ parametru w deklaracji funkcji variadic jest poprzedzony wielokropkiem, czyli (
). Oznacza to, że funkcja może być wywoływana z dowolną liczbą tego rodzaju parametrów.
Składnia:
function function-name(para1, para2...type)type{
// code
}
o W ramach funkcji
typ działa podobnie do plasterka. Załóżmy, że mamy sygnaturę funkcji, taką jak add(b…nt)int, a argument a jest typu []int.
o W funkcji variadic możesz również podać istniejący wycinek. Jak pokazano w drugim przykładzie, wysyłamy wycinek całej tablicy do funkcji, aby to zrobić.
o Gdy do funkcji variadic nie są przekazywane żadne argumenty, wycinek w obrębie funkcji jest równy zero.
o Funkcje wariacyjne są powszechnie używane do formatowania ciągów znaków.
o W metodzie variadycznej można również przekazać kilka przekrojów.
o Parametry Variadic nie mogą być używane jako wartości zwracane, chociaż mogą być zwracane jako wycinki.
Pierwszy przykład:
// Program to illustrate
// the concept of variadic function
package main
import(
"fmt"
"strings"
)
// Variadic function to join the strings
func joinstr(element...string)string{
return strings.Join(element, "-")
}
func main() {
// zero argument
fmt.Println(joinstr())
// the multiple arguments
fmt.Println(joinstr("Hello", "HEW"))
fmt.Println(joinstr("Hello", "Everyone",
"World"))
fmt.Println(joinstr("H", "E", "L", "L", "O"))
}
Drugi przykład:
// Program to illustrate
// the concept of variadic function
package main
import(
"fmt"
"strings"
)
// The Variadic function to join strings
func joinstr(element...string)string{
return strings.Join(element, "-")
}
func main() {
// pass a slice in the variadic function
element:= []string{"hello", "FROM", "world"}
fmt.Println(joinstr(element…))
}
Kiedy korzystamy z funkcji variadic:
o Funkcja variadic służy do przekazywania wycinka w funkcji.
o Używamy funkcji zmiennej, gdy nie znamy liczby parametrów.
o Kiedy używamy funkcji zmiennej w twoim oprogramowaniu, poprawia się czytelność.
Funkcje anonimowe
Funkcja anonimowa jest cechą języka programowania Go. Funkcja anonimowa nie ma nazwy, gdy musimy napisać funkcję wbudowaną. Anonimowa funkcja w Go może skonstruować zamknięcie. Funkcja anonimowa jest również określana jako literał funkcji.
Składnia:
func(parameter-list)(returntype){
// code
// Use the return statement if returntype are
given
// if returntype is not given, then do not
// use the return statement
return
}()
Przykład:
// Program to illustrate how
// to create anonymous function
package main
import "fmt"
func main() {
// the anonymous function
func(){
fmt.Println("Welcome to World")
}()
}
Ważne notatki:
o Anonimową funkcję można przypisać do zmiennej w języku programowania Go. Kiedy przypisujemy funkcję do zmiennej, typ zmiennej zmienia się na funkcję i możemy to nazwać wywołaniem funkcji, jak pokazano w poniższym przykładzie:
// Program to illustrate
// the use of an anonymous function
package main
import "fmt"
func main() {
// Assigning anonymous
// function to variable
value := func(){
fmt.Println("Welcome to World")
}
value()
}
o W funkcji anonimowej możemy również przekazywać parametry.
Przykład:
// Program to pass arguments
// in anonymous function
package main
import "fmt"func main() {
// Passing arguments in the anonymous function
func(ele string){
fmt.Println(ele)
}("Helloeveryone")
}
o Funkcja anonimowa może również zostać przekazana jako argument do innej funkcji.
Przykład:
// Program to pass an anonymous
// function as an argument into
// the other function
package main
import "fmt"
// Passing anonymous function
// as argument
func XYZ(i func(a, b string)string){
fmt.Println(i ("Hello", "for"))
}
func main() {
value:= func(a, b string) string{
return a + b + "Hello"
}
XYZ(value)
}
o Inna funkcja może również zwrócić funkcję anonimową.
Przykład:
// Program to illustrate
// the use of anonymous function
package main
import "fmt"
// Returning the anonymous function
func XYZ() func(a, b string) string{
myf := func(a, b string)string{
return a + b + "Everyone"
} return myf
}func main() {
value := XYZ()
fmt.Println(value("Hello ", "to "))
}
Funkcje GoLang main() i init().
Język programowania Go rezerwuje dwie funkcje do celów specjalnych:
main() i init().
Funkcja main()
Główny pakiet w Go to specjalny pakiet używany z aplikacjami wykonywalnymi, w tym z metodą main(). Funkcja main() jest unikalną funkcją, która służy jako punkt wejścia programu wykonywalnego. Nie przyjmuje ani nie zwraca żadnych argumentów. Go wywołuje metodę main() automatycznie, więc nie ma potrzeby jej bezpośredniego wywoływania, a każdy program wykonywalny musi mieć jeden pakiet główny i funkcję main().
Przykład:
// Program to illustrate
// the concept of main() function
// Declaration of main package
package main
// Importing packages
import (
"fmt"
"sort"
"strings"
"time"
)
// Main function
func main() {
// Sorting the given slice
st := []int{335, 79, 113, 14, 86, 12, 467, 9}
sort.Ints(st)
fmt.Println("Sorted slice: ", st)
// Finding the index
fmt.Println("Index value: ", strings.
Index("Hello", "ks"))
// Finding the time
fmt.Println("Time: ", time.Now().Unix())
}
Funkcja init()
Funkcja init(), podobnie jak funkcja main, nie przyjmuje żadnych argumentów i nic nie zwraca. Ta funkcja jest zawarta w każdym pakiecie i jest wywoływana, gdy pakiet jest ładowany po raz pierwszy. Ta funkcja jest zdefiniowana niejawnie, więc nie możemy uzyskać do niej dostępu w innym miejscu. Możemy skonstruować wiele funkcji init() w tej samej aplikacji i będą one wykonywane w kolejności, w jakiej zostały utworzone. Funkcje init() mogą być umieszczone w dowolnym miejscu programu i są wywoływane w leksykalnej kolejności nazw plików (porządek alfabetyczny). Dopuszczalne jest dołączanie instrukcji, jeśli używana jest funkcja init(), ale należy pamiętać, że metoda init() jest wykonywana przed wywołaniem funkcji main(); dlatego nie jest zależny od funkcji main(). Głównym celem funkcji init() jest inicjalizacja zmiennych globalnych, których nie można zainicjować w kontekście globalnym.
Przykład:
// Program to illustrate
// the concept of init() function
// Declaration of main package
package main
// the importing package
import "fmt"
// the multiple init() function
func init() {
fmt.Println("Welcome everyone")
}
func init() {
fmt.Println("Hello everyone ")
}
// the main function
func main() {
fmt.Println("Welcome to home")
}
Co to jest pusty identyfikator (podkreślenie) w GoLang?
W GoLang _(podkreślenie) jest określane jako pusty identyfikator. Identyfikatory to zdefiniowane przez użytkownika nazwy komponentów oprogramowania używane do identyfikacji. GoLang zapewnia funkcję, która pozwala nam zadeklarować i wykorzystać nieużywaną zmienną przy użyciu pustego identyfikatora. Nieużywane zmienne są definiowane przez użytkownika w całym programie, ale nigdy nie są przez niego wykorzystywane. Te zmienne sprawiają, że program jest prawie nieczytelny. Ponieważ GoLang jest bardziej zwięzłym i czytelnym językiem programowania, nie umożliwia programiście określenia niepotrzebnej zmiennej; jeśli to zrobimy, kompilator zgłosi błąd. Gdy funkcja zwraca kilka wartości, ale potrzebujemy tylko kilku z nich, a niektóre odrzucamy, możemy użyć pustego identyfikatora. Informuje kompilator, że ta zmienna nie jest potrzebna i może ją zignorować bez powodowania błędu. Ukrywa wartości zmiennych i czyni program zrozumiałym. W rezultacie za każdym razem, gdy podajemy wartość Identyfikatora banku, staje się on bezużyteczny.
Pierwszy przykład: W poniższym programie funkcja mul_div zwraca dwie wartości, które przechowujemy w identyfikatorach mul i div. Jednak w całym programie używamy tylko jednej zmiennej, mul. W rezultacie kompilator zgłosi błąd, jeśli element div zostanie zadeklarowany, ale nie zostanie wykorzystany.
// Program to show compiler
// throws an error if variable is
// declared but not used
package main
import "fmt"
// the main function
func main() {
// calling function
// function returns two values which are
// assigned to mul and div the identifier
mul, div := mul_div(110, 9)
// only using the mul variable
// compiler will give an error
fmt.Println("110 x 9 = ", mul)
}
// function returning the twov
// values of integer type
func mul_div(nm1 int, nm2 int) (int, int) {
// returning values
return nm1 * nm2, nm1 / nm2
}
Drugi przykład: Aby naprawić powyższy program, użyjmy Blank Identyfikator. Po prostu użyj _(podkreślenia) zamiast identyfikacji elementu div. Pozwala kompilatorowi zignorować zadeklarowany i niewykorzystany błąd dla tej konkretnej zmiennej.
// Program to the use of Blank identifier
package main
import "fmt"
// the main function
func main() {
// calling function
// function returns two values which are
// assigned to mul and blank identifier
mul, _ := mul_div(110, 8)
// only using the mul variable
fmt.Println("110 x 8 = ", mul)
}
// function returning the two
// values of integer type
func mul_div(nm1 int, nm2 int) (int, int) {
// returning the values
return nm1 * nm2, nm1 / nm2
}
Ważne notatki:
o Wiele pustych identyfikatorów może być używanych w tym samym programie. W rezultacie program GoLang może zawierać wiele zmiennych o tej samie nazwie identyfikatora, pusty identyfikator.
o Istnieje wiele sytuacji, w których wartości muszą zostać przypisane tylko po to, aby uzupełnić składnię, mimo że wartości nigdy nie będą wykorzystywane w programie. Jak w funkcji, która zwraca wiele wartości. W takich przypadkach często stosuje się pusty identyfikator.
o W przypadku pustego identyfikatora możemy wykorzystać dowolną wartość dowolnego typu.
SŁOWO KLUCZOWE DEFER
Instrukcje odroczenia w języku Go odkładają wykonanie funkcji lub metody albo metody anonimowej do czasu powrotu pobliskich funkcji. Odroczone parametry wywołania funkcji lub metody, innymi słowy, oceniają natychmiast, ale nie wykonują, dopóki nie powróci pobliska funkcja. Możemy skonstruować opóźnioną metodę, funkcję lub funkcję anonimową za pomocą słowa kluczowego defer.
Składnia:
// Function
defer func func-name(parameterlist Type)
returntype{
// Code
}
// Method
defer func (receiver Type)
methodname(parameterlist){
// Code
}
defer func (parameterlist)(returntype){
// code
}()
Ważne notatki:
o Wiele instrukcji odroczenia jest dozwolonych w tym samym programie w Go i są one wykonywane w sekwencji LIFO (Last-In, First-Out), jak pokazano w drugim przykładzie.
o Parametry instrukcji odroczenia są oceniane w momencie wykonania instrukcji odroczenia, a nie w momencie jej wywołania.
o Instrukcje odroczenia są powszechnie używane w celu zagwarantowania zamknięcia plików, gdy ich użycie nie jest już potrzebne, w celu zamknięcia kanału lub przechwycenia paniki w programie.
Zilustrujmy to pojęcie przykładem:
Pierwszy przykład:
// Program to illustrate
// the concept of the defer statement
package main
import "fmt"
// Functions
func mul(x1, x2 int) int {
rest := x1 * x2
fmt.Println("Result: ", rest)
return 0
}
func show() {
fmt.Println("Hello, Everyone")
}
// the main function
func main() {
// Calling the mul() function
// Here the mul function behaves
// like normal function
mul(43, 25)
// Calling the mul()function
// Using defer keyword
// Here mul() function
// is defer function
defer mul(27, 46)
// Calling show() function
show()
}
Objaśnienie: W powyższym przykładzie istnieją dwie metody o nazwach mul() i show() (). Podczas gdy funkcja show() jest zwykle wywoływana w funkcji main(), funkcja mul() jest wywoływana na dwa sposoby:
Najpierw wywołujemy funkcję mul normalnie (bez słowa kluczowego defer), tj. mul(43, 25), i jest ona wykonywana, gdy funkcja jest wywoływana. Po drugie, używamy słowa kluczowego defer, aby odnieść się do funkcji mul() jako funkcji odroczonej, tj. defer odrocz mul(27, 46) i wykonuje się, gdy wszystkie otaczające metody powrócą.
Drugi przykład:
// Program to illustrate
// the multiple defer statements, to illustrate
LIFO policy
package main
import "fmt"
// Functions
func add(x1, x2 int) int {
rest := x1 + x2
fmt.Println("Result: ", rest)
return 0
}
// the main function
func main() {
fmt.Println("Starting")
// Multiple defer statements
// Executes in the LIFO order
defer fmt.Println("Ending")
defer add(37, 59)
defer add(12, 12)
}
PANIC w GoLang
Panic, podobnie jak wyjątek, pojawia się podczas wykonywania w języku programowania G. Innymi słowy, panika pojawia się, gdy w programie Go wystąpi nieoczekiwana okoliczność, powodująca przerwanie wykonywania programu. Czasami panika pojawia się w czasie wykonywania, gdy pojawia się określony warunek, taki jak dostęp do tablicy poza zakresem, jak pokazano w pierwszym przykładzie, a innym razem jest to celowo rzucane przez programistę, aby obsłużyć najgorszy scenariusz w programie Go za pomocą panika(), jak pokazano w drugim przykładzie. Funkcja paniki jest nieodłączną funkcją zdefiniowaną we wbudowanym pakiecie języka Go. Ta funkcja zatrzymuje przepływ kontroli i zaczyna panikować.
Składnia:
func panic(v interface{})
Jest w stanie zaakceptować każdy rodzaj argumentacji. Gdy w programie Go wystąpi panika, program zatrzymuje się w czasie wykonywania, a na ekranie wyjściowym wyświetlany jest komunikat o błędzie i ślad stosu aż do punktu, w którym wystąpiła panika. Ogólnie rzecz biorąc, kiedy w programie Go pojawia się panika, program nie kończy się natychmiast; zamiast tego kończy się, gdy Go zakończy wszystkie oczekujące prace dla tego programu. Na przykład, jeśli funkcja A wywołuje panikę, wykonywanie funkcji A zostaje zatrzymane, a jeśli w A dostępne są jakieś opóźnione funkcje, działają one normalnie. Następnie funkcja A powraca do swojego wywołującego, a A zachowuje się jak wywołanie paniki do dzwoniącego. Jak widać w trzecim przykładzie, ta procedura jest kontynuowana, dopóki nie zostaną zwrócone wszystkie funkcje w bieżącym goroutine, kiedy to program kończy się niepowodzeniem.
Pierwszy przykład:
// Program which illustrates the
// concept of panic
package main
import "fmt"
// the main function
func main() {
// Creating array of string type
// Using the var keyword
var myarr [3]string
// Elements are assigned using an index
myarr[0] = "HE"
myarr[1] = "Helloeveryone"
myarr[2] = "Hello"
// Accessing elements
// of the array
// Using the index value
fmt.Println("The Elements of Array:")
fmt.Println("The Element 1: ", myarr[0])
// Program panics because the
// size of the array is 3
// we try to access
// the index 5 which is not
// available in current array,
// it gives an runtime error
fmt.Println("The Element 2: ", myarr[5])
}
Drugi przykład:
// Program which illustrates
// how to create own panic
// Using the panic function
package main
import "fmt"
// Function
func entry(lang *string, aname *string) {
// When value of lang
// is nil it will panic
if lang == nil {
panic("Error: The Language cannot be nil")
}
// When value of aname
// is nil it will panic
if aname == nil {
panic("Error: The Author name cannot be
nil")
}
// When values of the lang and aname
// are non-nil values it will print
// the normal output
fmt.Printf("The Author Language: %s \n Author
Name: %s\n", *lang, *aname)
}
// the main function
func main() {
A_lang := "GO-Language"
// Here in the entry function, we pass
// a non-nil, nil values
// Due to nil value this method panics
entry(&A_lang, nil)
}
Trzeci przykład:
// Program which illustrates
// the concept of Defer while panicking
package main
import (
"fmt"
)
// Function
func entry(lang *string, aname *string) {
// the Defer statement
defer fmt.Println("The Defer statement in the
entry function")
// When value of lang
// is nil it will panic
if lang == nil {
panic("Error: The Language cannot be nil")
}
// When value of aname
// is nil it will panic
if aname == nil {
panic("Error: The Author name cannot be
nil")
}
// When values of the lang and aname
// are non-nil values it will
// print the normal output
fmt.Printf("The Author Language: %s \n Author
Name: %s\n", *lang, *aname)
}
// the main function
func main() {
A_lang := "GO-Language"
// the Defer statement
defer fmt.Println("the Defer statement in the
main function")
// in entry function, we pass
// one non-nil and one-nil value
// Due to nil value this method panics
entry(&A_lang, nil)
}
Zauważ, że instrukcja lub funkcja Defer jest wykonywana zawsze, nawet jeśli program panikuje.
Użycie panic<
o Możemy użyć paniki, aby wskazać nienaprawialny błąd, w wyniku którego program nie może kontynuować działania.
o Jeśli chcemy, aby w naszym programie pojawił się błąd w określonych okolicznościach, możemy użyć panic.
ODZYSKIWANIE
Podobnie jak bloki try/catch w językach takich jak Java, C# i inne są używane do przechwytywania wyjątków, funkcja recovery w Go służy do obsługi paniki. Jest to wbudowana funkcja zdefiniowana we wbudowanym pakiecie języka Go. Ta metoda jest używana głównie do odzyskania kontroli nad spanikowanym goroutine. Innymi słowy, zajmuje się panicznym zachowaniem goroutine.
Składnia:
func recover() interface{}
Szybkie punkty
o Funkcja odzyskiwania jest zawsze wywoływana w ramach funkcji opóźnionej, a nigdy w funkcji zwykłej. Używając funkcji odzyskiwania z normalnej funkcji lub poza funkcją opóźnioną, sekwencja paniki jest kontynuowana, jak pokazano w pierwszym przykładzie. Jak pokazano w drugim przykładzie, funkcja odzyskiwania jest zawsze wywoływana wewnątrz funkcji odroczonej, ponieważ funkcja odroczona nie zatrzymuje swojego wykonywania, jeśli program panikuje, więc funkcja odzyskiwania zatrzymuje sekwencję paniki, po prostu przywracając normalne wykonanie goroutine i pobierając przekazaną wartość błędu na panikę.
o Funkcja przywracania będzie działać tylko wtedy, gdy wywołamy ją w tym samym trybie, w którym wystąpiła panika. Nie zadziała tak, jak pokazano w trzecim przykładzie, jeśli wywołamy go w oddzielnej goroutine.
o Jeśli chcemy znaleźć ślad stosu, skorzystajmy z metody PrintStack z pakietu Debug.
Pierwszy przykład:
// Program which illustrates
// the concept of recover
package main
import "fmt"
// This function is created to handle
panic occurs in entry function
// but it does not handle panic
occurred in entry function
// because it called in normal
function
func handlepanic() {
if a := recover(); a != nil {
fmt.Println("RECOVER", a)
}
}
// Function
func entry(lang *string, aname *string) {
// Normal function
handlepanic()
// When value of lang
// is nil it will panic
if lang == nil {
panic("Error: Language cannot be nil")
}
// When value of aname
// is nil it will panic
if aname == nil {
panic("Error: Author name cannot be nil")
}
fmt.Printf("The Author Language: %s \n Author
Name: %s\n", *lang, *aname)
fmt.Printf("Return successfully from entry
function")
}
// The main function
func main() {
A_lang := "GO Language"
entry(&A_lang, nil)
fmt.Printf("Return successfully from the main
function")
}
ZAMKNIĘCIE
Funkcja anonimowa jest cechą języka programowania Go. Anonimowa funkcja może stanowić zamknięcie. Zamknięcie jest rodzajem anonimowej funkcji, która odwołuje się do zmiennych określonych poza funkcją. Jest to analogiczne do dostępu do zmiennych globalnych dostępnych przed deklaracją funkcji.
Przykład:
// Program to illustrate how
// to create Closure
package main
import "fmt"
func main() {
// Declaring variable
HFW := 0
// Assigning an anonymous
// function to variable
counter := func() int {
HFW += 1
return HFW
}
fmt.Println(counter())
fmt.Println(counter())
}
Objaśnienie: Zmienna HFW nie została przekazana jako argument funkcji anonimowej, ale jest dostępna dla tej funkcji. Ten przykład ma niewielki problem, ponieważ każda inna funkcja określona w main musi mieć dostęp do zmiennej globalnej HFW i może ją aktualizować bez wywoływania funkcji licznika. W rezultacie zamknięcie zapewnia również inną korzyść: izolację danych.
// Program to illustrate how
// to create the data isolation
package main
import "fmt"
// newCounter function to
// isolate the global variable
func newCounter() func() int {
HFW := 0
return func() int {
HFW += 1
return HFW
}
}
func main() {
// newCounter function is assigned to a
variable
counter := newCounter()
// invoke the counter
fmt.Println(counter())
// invoke the counter
fmt.Println(counter())
}
Objaśnienie: Zamknięcie odwołuje się do zmiennej HFW nawet po zakończeniu funkcji newCounter(), ale żaden inny kod poza metodą newCounter() nie ma do niej dostępu. W ten sposób utrzymywana jest trwałość danych w wywołaniach funkcji, jednocześnie izolując dane z innych programów.
REKURENCJA
Rekurencja to proces, w którym funkcja wywołuje samą siebie, niejawnie lub jawnie, a powiązana funkcja jest znana jako funkcja rekurencyjna. Funkcja anonimowa jest szczególną cechą języka programowania Go. Jest to funkcja, która nie ma nazwy. Służy do tworzenia funkcji wbudowanej. Można również określić i zdefiniować anonimowe funkcje rekurencyjne. Rekurencyjne funkcje anonimowe są również określane jako literały funkcji rekurencyjnych.
Składnia
func(parameterlist)(returntype){
// code
// call the same function
// within function for recursion
// Use the return statement only
// if return-type are given.
return
}()
Pierwszy przykład :
// Program to show
// how to create recursive
// Anonymous function
package main
import "fmt"
func main() {
// Anonymous function
var recursiveAnonymous func()
recursiveAnonymous = func() {
// Printing message to show
// the function call and iteration.
fmt.Println("The Anonymous functions could
be recursive.")
// Calling the same function
recursively
recursiveAnonymous()
}
// the main calling of function
recursiveAnonymous()
}
Drugi przykład:
// Program to show
// how to create recursive
// Anonymous function
package main
import (
"fmt"
)
func main() {
// the Anonymous function
var recursiveAnonymous func(int)
// Passing arguments to Anonymous function
recursiveAnonymous = func(variable int) {
// Checking condition to return
if variable == -1 {
fmt.Println("Welcome to our Channel")
return
} else {
fmt.Println(variable)
// Calling the same
// function recursively
recursiveAnonymous(variable - 1)
}
}
// the main calling
// of function
recursiveAnonymous(10)
}
Typy rekurencji
Istnieje kilka odmian rekurencji, co ilustrują poniższe przykłady.
Bezpośrednia rekurencja
Rekurencja bezpośrednia to rodzaj rekurencji, w której funkcja wywołuje samą siebie bezpośrednio, bez pomocy innej funkcji. Poniższy przykład ilustruje koncepcję bezpośredniej rekurencji:
// Program to illustrate
// the concept of direct recursion
package main
import (
"fmt"
)
// the recursive function for
// calculating factorial of a positive integer
func factorial_calc(number int) int {
// this is base condition
// if number is 0 or 1 the function will return 1
if number == 0 || number == 1 {
return 1
}
// if the negative argument is
// given, it prints error message & returns -1
if number < 0 {
fmt.Println("Invalid-number")
return -1
}
// the recursive call to itself with argument
decremented
// by 1 integer so that it
// eventually reaches base case
return number*factorial_calc(number - 1)
}
// main function
func main() {
// passing 0 as a parameter
answer1 := factorial_calc(0)
fmt.Println(answer1, "\n")
// passing a positive integer
answer2 := factorial_calc(5)
fmt.Println(answer2, "\n")
// passing negative integer
// prints error message
// with return value of -1
answer3 := factorial_calc(-1)
fmt.Println(answer3, "\n")
// passing positive integer
answer4 := factorial_calc(10)
fmt.Println(answer4, "\n")
}
Rekurencja pośrednia
Rekurencja pośrednia to rodzaj rekurencji, w której funkcja wywołuje inną funkcję, która następnie wywołuje funkcję wywołującą. Inna funkcja służy do wspomagania tej formy rekurencji. Funkcja wywołuje samą siebie, ale robi to pośrednio za pośrednictwem innej funkcji. Poniższy przykład ilustruje koncepcję rekurencji pośredniej:
// Program to illustrate
// the concept of indirect recursion
package main
import (
"fmt"
)
// the recursive function for printing all numbers
// upto number x
func print_one(x int) {
// if number is positive
// print the number
// call second function
if x >= 0 {
fmt.Println("In first function:", x)
// call to the second function
// which calls this first
// function indirectly
print_two(x - 1)
}
}
func print_two(x int) {
// if number is positive
// print the number, call second function
if x >= 0 {
fmt.Println("In second function:", x)
// call to first function
print_one(x - 1)
}
}
// main function
func main() {
// passing positive
// parameter which prints all
// the numbers from 1 - 10
print_one(10)
// this will not print anything as it does not
// follow base case
print_one(-1)
}
Uwaga: Rekurencja wzajemna odnosi się do rekurencji pośredniej z tylko dwiema funkcjami. Aby wspomóc rekurencję pośrednią, może istnieć więcej niż dwie funkcje.
Rekurencja ogona
Wywołanie ogona to wywołanie podprogramu, które jest ostatnim lub ostatnim wywołaniem funkcji. Kiedy wywołanie ogona ponownie wywołuje tę samą funkcję, mówi się, że funkcja jest rekurencyjna ogona. Wywołanie rekurencyjne jest ostatnią czynnością wykonywaną przez funkcję w tym przypadku.
Przykład:
// Program to illustrate
// the concept of tail recursion
package main
import (
"fmt"
)
// the tail recursive function
// to print all the numbers
// from x to 1
func print_num(x int) {
// if number is still
// positive, print it
// and call the function
// with decremented value
if x > 0 {
fmt.Println(x)
// last statement in
// the recursive function
// tail recursive call
print_num(x-1)
}
}
// the main function
func main() {
// passing positive
// number, prints 5 to 1
print_num(5)
}
Rekurencja głowy
Wywołanie rekurencyjne jest początkową instrukcją w funkcji w rekurencji głowy. Nie ma żadnych dalszych instrukcji ani operacji poprzedzających wywołanie. Funkcja nie musi niczego przetwarzać po wywołaniu, a wszystkie operacje są zakończone po powrocie.
Przykład:
// Program to illustrate
// the concept of head recursion
package main
import (
"fmt"
)
// the head recursive function
// to print all the numbers
// from 1 to x
func print_num(x int) {
// if the number is still
// less than x, call
// function with decremented value
if x > 0 {
// the first statement in function
print_num(x-1)
// printing is done at
// the returning time
fmt.Println(x)
}
}
// the main function
func main() {
// passing positive
// number, prints 5 to 1
print_num(5)
}
Uwaga: Warto zauważyć, że wynik rekurencji głowy jest dokładnie odwrotny do wyniku rekurencji ogona. Dzieje się tak dlatego, że w rekurencji ogonowej funkcja najpierw wypisuje liczbę, a następnie wywołuje samą siebie, ale w rekurencji czołowej funkcja wywołuje samą siebie, dopóki nie osiągnie przypadku podstawowego, a następnie rozpoczyna drukowanie podczas powrotu.
Nieskończona rekurencja
Wszystkie funkcje rekurencyjne były określonymi lub skończonymi funkcjami rekurencyjnymi, co oznacza, że kończyły się, gdy osiągnęły warunek podstawowy. Rekurencja nieskończona to rekurencja, która nigdy nie jest zbieżna do przypadku podstawowego i trwa w nieskończoność. To często prowadzi do awarii systemu lub wycieków pamięci.
Przykład:
// Program to illustrate
// the concept of infinite recursion
package main
import (
"fmt"
)
// infinite-recursion function
func print_hello() {
// printing infinite-times
fmt.Println("Helloeveryone")
print_hello()
}
// the main function
func main() {
// call to infinite recursive-function
print_hello()
}
Rekurencja funkcji anonimowej
W GoLang istnieje koncepcja znana jako funkcje, które nie mają nazwy. Są to tak zwane funkcje anonimowe. Anonimowe funkcje w GoLang mogą być również używane do rekurencji, jak widać w poniższych przykładach.
Pierwszy przykład:
// Program to illustrate
// the concept of anonymous function recursion
package main
import (
"fmt"
)
// main function
func main() {
// declaring anonymous function
// that takes integer value
var anon_func func(int)
// defining the anonymous
// function that prints the numbers from x to 1
anon_func = func(number int) {
// the base case
if number == 0 {
return
} else {
fmt.Println(number)
// calling anonymous function
recursively
anon_func(number-1)
}
}
// call to anonymous recursive function
anon_func(5)
}
Drugi przykład:
// Program which illustrates the
// concept of recover
package main
import (
"fmt"
)
// This function handles panic
// occur in the entry function
// with help of the recover function
func handlepanic() {
if x := recover(); x != nil {
fmt.Println("RECOVER", x)
}
}
// Function
func entry(lang *string, aname *string) {
// the Deferred function
defer handlepanic()
// When value of lang is nil it will panic
if lang == nil {
panic("Error: The Language cannot be nil")
}
// When value of aname
// is nil it will panic
if aname == nil {
panic("Error: The Author name cannot be
nil")
}
fmt.Printf("The Author Language: %s \n Author
Name: %s\n", *lang, *aname)
fmt.Printf("The Return successfully from entry
function")
}
// the main function
func main() {
A_lang := "GO-Language"
entry(&A_lang, nil)
fmt.Printf("The Return successfully from main
function")
}
Trzeci przykład
// Program which illustrates
// the recover in a goroutine
package main
import (
"fmt"
"time"
)
// For the recovery
func handlepanic() {
if x := recover(); x != nil {
fmt.Println("RECOVER", x)
}
}
/* Here, this panic is not handled by recover
function because of recover function is not
called in the same goroutine in which
panic occurs */
// the Function 1
func myfun1() {
defer handlepanic()
fmt.Println("Welcome to the Function1")
go myfun2()
time.Sleep(10 * time.Second)
}
// the Function 2
func myfun2() {
fmt.Println("Welcome to Function2")
panic("Panicked!!")
}
// the main function
func main() {
myfun1()
fmt.Println("The Return successfully from main
function")
}
Wskaźniki
WSKAŹNIKI GoLang
Wskaźniki to zmienne w języku programowania Go lub GoLang używane do przechowywania adresu pamięci innej zmiennej. Wskaźniki są również znane jako zmienne specjalne w GoLangu. Zmienne służą do przechowywania danych w systemie pod określonym adresem pamięci. Adresy pamięci są zawsze w formacie szesnastkowym (zaczynając od 0x jak 0xFFAAF itd.).
Jaki jest cel wskaźnika?
Aby zrozumieć tę potrzebę, musimy najpierw zrozumieć ideę zmiennych. Zmienne to nazwy przypisane do lokalizacji pamięci, w których przechowywane są rzeczywiste dane. Aby odzyskać zapisane dane, musimy znać adres tej konkretnej lokalizacji pamięci. Ręczne zapamiętywanie wszystkich lokalizacji pamięci (format szesnastkowy) jest narzutem, dlatego używamy zmiennych do przechowywania danych, a zmienne można pobrać po prostu za pomocą ich nazwy. GoLang pozwala nam również zapisać liczbę szesnastkową do zmiennej przy użyciu wyrażenia dosłownego, co oznacza, że każda liczba zaczynająca się od 0x jest liczbą szesnastkową.
Przykład: W poniższym programie zapisujemy liczbę szesnastkową w zmiennej. Widzimy jednak, że typem wartości jest int i jest ona zapisywana jako wartość dziesiętna lub możemy powiedzieć, że przechowywana jest wartość dziesiętna typu int. Ale istotą tego przykładu jest to, że przechowujemy wartość szesnastkową, ale nie jest to wskaźnik, ponieważ nie odnosi się do miejsca w pamięci innej zmiennej. Jest to po prostu zmienna określona przez użytkownika. W rezultacie wymagane są wskaźniki.
// Program to demonstrate the variables
// storing hexadecimal values
package main
import "fmt"
func main() {
// storing hexadecimal
// values in the variables
c := 0xFF
d := 0x9C
// Displaying values
fmt.Printf("The Type of variable x is %T\n", c)
fmt.Printf("The Value of x in hexadecimal is
%X\n", c)
fmt.Printf("The Value of x in decimal is
%v\n", c)
fmt.Printf("The Type of variable y is %T\n", d)
fmt.Printf("The Value of y in hexadecimal is
%X\n", d)
fmt.Printf("The Value of y in decimal is
%v\n", d)
}
Wskaźnik jest rodzajem zmiennej, która zawiera adresy pamięci innych zmiennych i punktów, w których znajduje się pamięć, oraz podaje metody określania wartości przechowywanej w tej lokalizacji pamięci. Czasami jest określany jako specjalny typ zmiennej, ponieważ jest praktycznie dokładnie określony jako zmienna, ale z * (operator dereferencji).
Deklaracja i inicjalizacja wskaźników
Zanim zaczniemy, we wskaźnikach użyjemy dwóch kluczowych operatorów, a mianowicie:
o Operator dereferencji "*", powszechnie znany jako operator zmiennej wskaźnika, służy do definiowania zmiennej wskaźnika i uzyskiwania dostępu do wartości zawartej w adresie.
o Operator &, znany również jako operator adresu, służy do zwracania adresu zmiennej lub pobierania adresu zmiennej za pomocą wskaźnika.
Deklarowanie wskaźnika
var pointername *Data_Type
Jako przykład rozważmy następujący wskaźnik łańcuchowy, który może zawierać tylko adresy pamięci zmiennych łańcuchowych.
var st *string
Inicjalizacja wskaźnika
Aby to zrobić, użyj operatora adresu, aby zainicjować wskaźnik adresem pamięci innej zmiennej, jak pokazano w poniższym przykładzie:
// the normal variable declaration
var x = 45
// Initialization of pointer st with
// the memory address of variable x
var st *int = &x
Przykład:
// program to demonstrate declaration and
// initialization of pointers
package main
import "fmt"
func main() {
// taking normal variable
var a int = 4798
// the declaration of pointer
var b *int
// the initialization of pointer
b = &a
// displaying result
fmt.Println("The Value stored in a = ", a)
fmt.Println("The Address of a = ", &a)
fmt.Println("The Value stored in variable b =
", b)
}
Ważne uwagi
1. Wartość domyślna lub zerowa wskaźnika to zawsze zero. Alternatywnie, niezainicjowany wskaźnik zawsze będzie miał wartość zero.
Przykład:
// Program to demonstrate the
// nil value of the pointer
package main
import "fmt"
func main() {
// taking pointer
var st *int
// displaying result
fmt.Println("st = ", st)
}
2. Deklarację i inicjalizację wskaźników można wykonać w jednej linii.
Przykład:
var st *int = &x
3. Jeśli oprócz deklaracji wskaźnika wymienimy typ danych, wskaźnik będzie w stanie obsłużyć lokalizację pamięci określonej zmiennej typu danych. Na przykład, jeśli weźmiemy wskaźnik typu łańcuchowego, adres zmiennej, którą podamy wskaźnikowi, będzie tylko zmienną typu danych łańcuchowych, a nie jakiegokolwiek innego rodzaju.
4. Aby uniknąć powyższego problemu, możemy skorzystać z koncepcji wnioskowania o typie słowa kluczowego var. Typ danych nie musi być określony podczas deklaracji. Kompilator może określić typ zmiennej wskaźnika w taki sam sposób, jak typ zwykłej zmiennej. W tym przypadku nie będziemy używać operatora *. Zostanie on określony wewnętrznie przez kompilator, gdy inicjujemy zmienną przy użyciu adresu innej zmiennej.
Przykład :
// Program to demonstrate the
// use of type inference in
// the pointer variables
package main
import "fmt"
func main() {
// using the var keyword
// we are not defining any type with the
variable
var x = 328
// taking pointer variable using
// the var keyword without specifying the type
var a = &x
fmt.Println("The Value stored in x = ", x)
fmt.Println("The Address of x = ", &x)
fmt.Println("The Value stored in pointer
variable a = ", a)
}
5. Możemy alternatywnie zdefiniować i zainicjować zmienne wskaźnikowe używając składni skróconej (:=). Jeśli przekażemy jej adres zmiennej za pomocą operatora &(address), kompilator wewnętrznie określi zmienną wskaźnika.
Przykład:
// program to demonstrate the
// use of shorthand syntax in Pointer variables
package main
import "fmt"
func main() {
// using the := operator to declare and
// initialize the variable
x := 328
// taking pointer variable using
// := by assigning it with
// the address of variable y
a := &x
fmt.Println("The Value stored in x = ", x)
fmt.Println("The Address of x = ", &x)
fmt.Println("The Value stored in pointer
variable a = ", a)
}
Wskaźnik dereferencji
Operator * jest również znany jako operator dereferencji. Służy nie tylko do określania zmiennej wskaźnikowej, ale także do uzyskiwania dostępu do wartości zmiennej, na którą wskazuje wskaźnik, w procesie znanym jako pośrednie lub dereferencyjne. Wartość w lokalizacji jest czasami nazywana operatorem *. Spójrzmy na przykład, który pomoże nam zrozumieć to pojęcie:
// Program to illustrate
// the concept of dereferencing a pointer
package main
import "fmt"
func main() {
// using the var keyword
// we are not defining any type with the variable
var x = 328
// taking pointer variable using
// the var keyword without specifying the type
var a = &x
fmt.Println("The Value stored in x = ", x)
fmt.Println("The Address of x = ", &x)
fmt.Println("The Value stored in pointer variable
a = ", a)
// this is dereferencing a pointer
// using * operator before the pointer
// variable to access value stored at the variable
at which it is pointing
fmt.Println("The Value stored in y(*a) = ", *a)
}
Zamiast przypisywać zmiennej nową wartość, możemy zmienić wartość wskaźnika lub miejsca w pamięci.
Przykład :
// Program to illustrate the above mentioned
concept
package main
import "fmt"
func main() {
// using the var keyword
// we are not defining any type with the variable
var x = 458
// taking pointer variable using
// the var keyword without specifying the type
var a = &x
fmt.Println("The Value stored in y before
changing = ", x)
fmt.Println("The Address of x = ", &x)
fmt.Println("The Value stored in pointer
variable a = ", a)
// this is dereferencing pointer
// using the * operator before pointer
// variable to access value stored at the
variable at which it is pointing
fmt.Println("The Value stored in x(*a) Before
Changing = ", *a)
// changing the value of x by assigning
// the new value to the pointer
*a = 500
fmt.Println("Value stored in x(*a) after
Changing = ",x)
}
Jak w GoLangu możemy utworzyć instancję struct za pomocą nowego słowa kluczowego?
Struct służy głównie jako kontener dla wszystkich innych typów danych. Możemy łatwo manipulować/uzyskiwać dostęp do danych przydzielonych do struktury, wykorzystując odwołanie do struktury. W GoLangu możemy utworzyć strukturę za pomocą słowa kluczowego new oraz operatora adresu wskaźnika, jak pokazano w poniższym przykładzie.
Przykład: W tym przypadku widzimy, że tworzymy instancję struktury za pomocą słowa kluczowego new.
// Program to show how to instantiate struct
// using new keyword
package main
import "fmt"
type emp struct {
name string
empid int
salary int
}
func main() {
// emp1 is a pointer to an instance of emp
// using the new keyword
emp1 := new(emp)
emp1.name = "ABC"
emp1.empid = 2325
emp1.salary = 37000
fmt.Println(emp1)
// emp2 is an instance of emp
var emp2 = new(emp)
emp2.name = "XYZ"
emp2.salary = 40000
fmt.Println(emp2)
}
WSKAŹNIKI DO FUNKCJI
Wskaźniki to zmienne w języku programowania Go lub GoLang używane do przechowywania adresu pamięci innej zmiennej. Możemy również przekazywać wskaźniki do funkcji w taki sam sposób jak zmienne. Można to osiągnąć na dwa sposoby.
Utwórz wskaźnik i przekaż go do funkcji
W poniższym programie używamy funkcji ptf z parametrem wskaźnika typu całkowitego, instruując funkcję, aby akceptowała tylko argumenty typu wskaźnika. Ta funkcja zasadniczo zmodyfikowała wartość zmiennej y. Na początku y ma wartość 200. Jednak po wywołaniu funkcji wartość zmieniła się na 638, co widać na wyjściu.
// Program to create a pointer and
// passing it to the function
package main
import "fmt"
// taking function with integer
// the type pointer as an parameter
func ptf(b *int) {
// dereferencing
*b = 638
}
// the main function
func main() {
// taking normal variable
var y = 200
fmt.Printf("Value of y before function call
is: %d\n", y)
// taking pointer variable and
// assigning the address
// of y to it
var pb *int = &y
// calling tfunction by
// passing the pointer to function
ptf(pb)
fmt.Printf("Value of y after function call is:
%d\n", y)
}
Przekazywanie adresu zmiennej do wywołania funkcji
W poniższym programie nie tworzymy wskaźnika do przechowywania adresu zmiennej y, jak to zrobiliśmy w poprzednim programie. Bezpośrednio przekazujemy adres y do wywołania funkcji, które działa w taki sam sposób, jak wcześniej podany sposób.
// Program to create a pointer and
// passing address of the variable to the function
package main
import "fmt"
// taking function with integer
// the type pointer as an parameter
func ptf(b *int) {
// dereferencing
*b = 638
}
// the main function
func main() {
// taking normal variable
var y = 200
fmt.Printf("Value of y before function call is:
%d\n", y)
// calling the function by
// passing address of
// the variable y
ptf(&y)
fmt.Printf("Value of y after function call is:
%d\n", y)
}
Uwaga: Zmienne i wskaźniki w poprzednich programach można również deklarować za pomocą operatora krótkiej deklaracji (:=).
WSKAŹNIK DO STRUKTURY
Wskaźnik to zmienna przechowująca adres pamięci innej zmiennej. Wskaźniki są również znane jako zmienne specjalne w GoLangu. Zmienne służą do przechowywania danych w systemie pod określonym adresem pamięci. Można również użyć wskaźnika do struktury. W GoLang struktura jest typem zdefiniowanym przez użytkownika, który pozwala nam grupować/łączyć elementy możliwie różnych rodzajów w jeden typ. Aby użyć wskaźnika do struktury, użyj operatora &, znanego również jako operator adresu. GoLang pozwala programistom używać wskaźników do uzyskiwania dostępu do pól struktury bez jawnego dereferencji.
Pierwszy przykład: Stworzymy strukturę o nazwie Pracownik, która zawiera dwie zmienne. Utwórz instancję struktury, tj. emp, w funkcji main. Następnie możemy wysłać adres struktury do wskaźnika, który reprezentuje wskaźnik do idei struktury. Nie ma potrzeby jawnego używania dereferencji, ponieważ zapewni to taki sam efekt, jak pokazano w następującym programie:
// Program to illustrate
// the concept of the Pointer to struct
package main
import "fmt"
// taking structure
type Employee struct {
// taking the variables
name string
empid int
}
// the main Function
func main() {
// creating instance of the Employee struct type
emp := Employee{"XYZ", 17028}
// Here, it is the pointer to struct
pts := &emp
fmt.Println(pts)
// accessing struct fields using pointer
// but here we are not using
// the dereferencing explicitly
fmt.Println(pts.name)
// same as above by explicitly using the
// dereferencing concept means
// the result will be the same
fmt.Println((*pts).name)
}
Drugi przykład: możemy również użyć wskaźnika do zmiany wartości elementów struktury lub literałów struktury, jak widać w poniższym programie:
// Program to illustrate
// the concept of Pointer to struct
package main
import "fmt"
// taking structure
type Employee struct {
// taking the variables
name string
empid int
}
// the main Function
func main() {
// creating instance of the
// Employee struct type
emp := Employee{"XYZ", 12038}
// Here, it is the pointer to struct
pts := &emp
// displaying values
fmt.Println(pts)
// updating value of name
pts.name = "ABC"
fmt.Println(pts)
}
WSKAŹNIK DO WSKAŹNIKA (PODWÓJNY WSKAŹNIK) W Go
Wskaźniki to zmienne w języku programowania Go lub GoLang używane do przechowywania adresu pamięci innej zmiennej. Ponieważ wskaźnik jest zmienną specjalną, może wskazywać na dowolną zmienną, nawet na inny wskaźnik. Zasadniczo wydaje się, że jest to łańcuch wskaźników. Kiedy definiujemy wskaźnik do wskaźnika, pierwszy wskaźnik przechowuje adres drugiego wskaźnika. Podwójne wskaźniki to inna nazwa tej koncepcji.
Jak zadeklarować wskaźnik do wskaźnika
Deklarowanie wskaźnika do wskaźnika jest tym samym, co deklarowanie wskaźnika w Go. Różnica polega na tym, że przed nazwą wskaźnika musimy umieścić dodatkowe "*". Zwykle dzieje się tak, gdy deklarujemy zmienną wskaźnika za pomocą słowa kluczowego var i typu. Poniższe przykłady i ilustracje znacznie lepiej zilustrują tę koncepcję. Pierwszy przykład: W poniższym programie wskaźnik pt2 zapisuje położenie wskaźnika pt1. Dereferencja pt2, tj. *pt2, zwraca adres zmiennej V lub wartość wskaźnika pt1. Jeśli spróbujemy **pt2, otrzymasz wartość zmiennej V, która wynosi 200.
// Program to illustrate
// the concept of the Pointer to Pointer
package main
import "fmt"
// the main Function
func main() {
// taking variable
// of the integer type
var V int = 200
// taking a pointer
// of integer type
var pt1 *int = &V
// taking pointer to
// pointer to pt1
// storing the address
// of pt1 into pt2
var pt2 **int = &pt1
fmt.Println("Value of Variable V is = ", V)
fmt.Println("The Address of variable V is = ",
&V)
fmt.Println("Value of pt1 is = ", pt1)
fmt.Println("The Address of pt1 is = ", &pt1)
fmt.Println("Value of pt2 is = ", pt2)
// Dereferencing pointer to pointer
fmt.Println("The Value at the address of pt2
is or *pt2 = ", *pt2)
// double pointer will give the value of
variable V
fmt.Println("*(The Value at the address of pt2
is) or **pt2 = ", **pt2)
}
Drugi przykład: Wprowadźmy pewne zmiany w poprzednim programie. Przypisywanie nowej wartości do wskaźników poprzez modyfikację ich wartości za pomocą dereferencji, jak widać w poniższym programie:
// Program to illustrate
// the concept of Pointer to Pointer
package main
import "fmt"
// the main Function
func main() {
// taking variable
// of the integer type
var v int = 200
// taking pointer
// of the integer type
var pt1 *int = &v
// taking pointer to
// the pointer to pt1
// storing address
// of pt1 into pt2
var pt2 **int = &pt1
fmt.Println("Value of Variable v is = ", v)
// changing value of v by assigning
// new value to the pointer pt1
*pt1 = 400
fmt.Println("The Value stored in v after
changing pt1 = ", v)
// changing value of v by assigning
// the new value to the pointer pt2
**pt2 = 600
fmt.Println("The Value stored in v after
changing pt2 = ", v)
}
PORÓWNANIE WSKAŹNIKÓW
Wskaźniki to zmienne w języku programowania Go lub GoLang używane do przechowywania adresu pamięci innej zmiennej. Wskaźniki są również znane jako zmienne specjalne w GoLangu. Zmienne służą do przechowywania danych w systemie pod określonym adresem pamięci. Adresy pamięci są zawsze w formacie szesnastkowym (zaczynając od 0x jak 0xFFAAF itd.). W języku programowania Go możemy porównać dwa wskaźniki. Dwie wartości wskaźników są identyczne tylko wtedy, gdy wskazują na to samo miejsce w pamięci lub są zerowe. Możemy porównywać wskaźniki za pomocą operatorów == i != podanych w języku programowania Go:
1. Operator ==: Zwraca wartość true, jeśli oba wskaźniki wskazują na tę samą zmienną. Alternatywnie, jeśli oba wskaźniki odnoszą się do różnych zmiennych, zwróć wartość false.
Składnia:
pointer_1 == pointer_2
Przykład:
// program to illustrate
// the concept of comparing two pointers
package main
import "fmt"
func main() {
val1 := 5325
val2 := 469
// Creating, initializing pointers
var p1 *int
p1 = &val1
p2 := &val2
p3 := &val1
// Comparing the pointers with each other
// Using == operator
res1 := &p1 == &p2
fmt.Println("Is p1 pointer is equal to the p2
pointer: ", res1)
res2 := p1 == p2
fmt.Println("Is p1 pointer is equal to the p2
pointer: ", res2)
res3 := p1 == p3
fmt.Println("Is p1 pointer is equal to the p3
pointer: ", res3)
res4 := p2 == p3
fmt.Println("Is p2 pointer is equal to the p3
pointer: ", res4)
res5 := &p3 == &p1
fmt.Println("Is p3 pointer is equal to the p1
pointer: ", res5)
}
2. Operator !=: Jeśli oba wskaźniki odnoszą się do tej samej zmiennej, ten operator zwraca fałsz. Zamiast tego, jeśli oba wskaźniki odnoszą się do oddzielnych zmiennych, zwróć wartość true.
Składnia:
pointer_1 != pointer_2
Przykład:
// Program to illustrate
// the concept of comparing two pointers
package main
import "fmt"
func main() {
val1 := 22459
val2 := 467
// Creating, initializing pointers
var p1 *int
p1 = &val1
p2 := &val2
p3 := &val1
// Comparing the pointers with each other
// Using the != operator
res1 := &p1 != &p2
fmt.Println("Is p1 pointer not equal to the p2
pointer: ", res1)
res2 := p1 != p2
fmt.Println("Is p1 pointer not equal to the p2
pointer: ", res2)
res3 := p1 != p3
fmt.Println("Is p1 pointer not equal to the p3
pointer: ", res3)
res4 := p2 != p3
fmt.Println("Is p2 pointer not equal to the p3
pointer: ", res4)
res5 := &p3 != &p1
fmt.Println("Is p3 pointer not equal to the p1
pointer: ", res5)
}