fbpx
devstyle.pl - Blog dla każdego programisty
devstyle.pl - Blog dla każdego programisty
7 minut

Golang #2 – typy proste oraz konstrukcje sterujące


29.05.2019

W tym artykule omówimy dwa tematy, bez których programowanie jest niemożliwe: typy oraz instrukcje sterujące. Golang idzie w kierunku maksymalnej prostoty, lecz nie prostactwa. W związku z tym typów nie wbudowano zbyt wiele, a instrukcji sterujących jest ledwie kilka. Co ważne, nie ujmuje to możliwościom tego języka.

Typy proste

Golang ma prosty system typów podstawowych, które możemy wykorzystać w naszych programach. Oczywiście nie ze wszystkich korzysta się na co dzień, lecz dobrze wiedzieć o ich istnieniu. Typy proste w golang wyglądają następująco:

  • bool – odpowiadająca za prawdę/fałsz (true/false),
  • string – tekst,
  • int – liczba całkowita wraz z różnymi zakresami: int8, int16, int32 oraz int64,
  • uint – liczba naturalna (czyli bez liczb ujemnych) wraz z różnymi zakresami: int8, int16, int32 oraz int64,
  • float32 oraz float64 – liczby zmiennoprzecinkowe,
  • complex64 oraz complex128 – liczby z częścią urojoną (czyli np. a + bi).

Nie będziemy od razu omawiać wszystkich typów, gdyż jest to nudne i… niepotrzebne. Przynajmniej na początku. Przyjrzyjmy się zatem programowi pokazującemu, w jaki sposób można stworzyć zmienne różnego typu oraz wyświetlić ich wartość.

func main() {
	fmt.Printf("Type: bool Value: %v\n", bool(true))
	fmt.Printf("Type: string Value: %v\n", string("hello, golang"))
	fmt.Printf("Type: int Value: %v\n", int(8))
	fmt.Printf("Type: float64 Value: %v\n", float64(15.6))
}

Użyłem tutaj trochę bardziej gadatliwego sposobu tworzenia tych zmiennych. Można to też uprościć do formy jak poniżej:

func main() {
	fmt.Printf("Type: bool Value: %v\n", true)
	fmt.Printf("Type: string Value: %v\n", "hello, golang")
	fmt.Printf("Type: int Value: %v\n", 8)
	fmt.Printf("Type: float64 Value: %v\n", 15.6)
}

Golang jest w stanie domyślić się typu zmiennej, której używamy. To pierwszy moment, w którym ten język ułatwia nam pracę, robiąc coś za nas. Gdy deklarujemy jakąś wartość i zapisujemy ją do zmiennej, to nie musimy podawać jej typu. Kompilator wykona operację automatycznie.

Dzięki temu mechanizmowi możemy zainicjować zmienną na kilka różnych sposobów:

var someInt int = 123
var anotherInt = 123
andAnotherInt := 123

Te trzy zapisy są równoważne. W pierwszym przykładzie przed nazwą zmiennej używamy słowa kluczowego var, następnie deklarujemy nazwę zmiennej oraz jej typ. Na końcu, po znaku równości, podajemy interesującą nas wartość. Drugi zapis jest trochę prostszy, gdyż pomijamy typ zmiennej – kompilator domyśli się go za nas na podstawie tego, co znajduje się po prawej stronie znaku równości.

Trzeci zapis jest najbardziej zwięzły, gdyż pomija całkowicie zarówno typ, jak i słowo kluczowe var, lecz przed znakiem równości dodany jest dwukropek. Przy owym dwukropku na chwilę się zatrzymamy.

Przy tym zapisie dwukropek dajemy tylko wtedy, gdy tworzymy nową zmienną, co znaczy, że gdy przypisujemy nową wartość do istniejącej zmiennej, to dwukropek pomijamy. W związku z tym poprawny będzie zapis jak poniżej:

var myVariable := 1234
// ... 
myVariable = 4321

Ostatnim typem, który omówimy, jest interface{}, czyli pusty interfejs. Zmienna tego typu może zawierać wszystko – może to być liczba całkowita, liczba zmiennoprzecinkowa czy struktura. Powinieneś starać się unikać stosowania pustego interfejsu, gdyż często jest to zła praktyka. Jednakże czasami okazuje się bardzo pomocna i należy pamiętać o jej istnieniu.

var myVariable interface{} // I can be anything
myVariable = 4321
myVariable = "juppi"
myVariable = 1.5

Instrukcje sterujące

Jeśli znamy już cały wachlarz typów zmiennych, możemy przejść do instrukcji sterujących. W języku golang, w związku z jego prostotą, nie ma ich za wiele. Omówmy więc po kolei każdą z nich.

Instrukcja warunkowa if

Praktycznie nie ma programu bez warunków. Pierwszą instrukcją warunkową, jaką poznamy, jest instrukcja if, która wygląda następująco:

myVariable := 123
	
if myVariable == 321 {
    fmt.Println("we are equal")
}

Golang play

To, o czym należy pamiętać, to fakt, że rozpoczynająca klamra winna być w tej samej linii co słówko if. Jeśli będziemy chcieli zapisać ją w nowej linii, nastąpi błąd kompilacji.

myVariable := 123
	
if myVariable == 321
{ // błąd – nie skompiluje się!
    fmt.Println("we are equal")
}

Golang play

Bardzo pomocne jest także to, że jeżeli zastąpimy podwójny znak równości pojedynczym, to również otrzymamy błąd. Ma to zapobiec sytuacjom, w których zapominamy dodać ten znak i musimy poświęcić trochę czasu (oraz nerwów) na znalezienie błędu.

myVariable := 123
	
if myVariable = 321 {
    fmt.Println("we are equal")
}

Golang play

Co ciekawe, jesteśmy w stanie wewnątrz warunku zadeklarować zmienną. Operacja ta pozwoli nam skrócić nieco kod oraz sprawi, że ten warunek będzie bardziej czytelny. Przypisanie wartości zmiennej oraz warunek oddzielamy znakiem średnika.

if err := someFunction(); err != nil {
	fmt.Printf("no error")
}

Golang play

Możemy też oczywiście napisać kod, który wykona się, gdy warunek zawarty w „if” nie będzie spełniony. Obrazuje to poniższy przykład.

myVariable := 123

if myVariable == 321 {
	fmt.Println("we are equal")
} else {
	fmt.Println("we are NOT equal 321")
}

Golang play

I tutaj warto pamiętać o tym, że klamra otwierająca powinna być w tej samej linii co słówko kluczowe else. W przeciwnym wypadku otrzymamy błąd kompilacji.

Instrukcja sterująca switch

Inną bardzo prostą instrukcją sterującą jest instrukcja switch. Można o niej powiedzieć to, że jest inną formą zapisu kombinacji if–else–if–else. To oznacza, że każdego switcha można zastąpić szeregiem if–else, jak i na odwrót.

animal := "dog"
	
switch animal {
case "cat":
	fmt.Println("Cats rulez!")
	break
case "dog":
	fmt.Println("Dogs rulez!")
	break
case "cow":
	fmt.Println("Muuuu rulez!")
	break
}

Golang play

Gdy żaden z przypadków nie wystąpił, to możemy użyć instrukcji default, która zostanie wykonana właśnie w takiej sytuacji.

animal := "chicken"
	
switch animal {
case "cat":
	fmt.Println("Cats rulez!")
	break
case "dog":
	fmt.Println("Dogs rulez!")
	break
case "cow":
	fmt.Println("Muuuu rulez!")
	break
default:
	fmt.Println("I do not know the animal…")
}

Golang play

Switche są często używane do wykonywania pewnych operacji w zależności od typu. Typ danej zmiennej można odczytać, pisząc myVariable.(type).

var myVariable interface{}
myVariable = 123

switch a := myVariable.(type) {
case int:
	fmt.Println("I am an integer!", a)
case string:
	fmt.Println("I am a string, cool", a)
default:
	fmt.Println("I do not know what type I am, but I am not a string or int", a)
}

Golang play

Podsumowanie

Istnieje też inna instrukcja sterująca, a mianowicie select, lecz ją zostawiam na jedną z kolejnych lekcji. Jak widać, zarówno typy, jak i instrukcje sterujące są bardzo proste i stosuje się je podobnie jak w innych językach. Zachęcam do eksperymentowania i pobawienia się tym, czego się nauczyłaś/nauczyłeś dzisiaj.

Nie przegap kolejnych postów!

Dołącz do ponad 9000 programistów w devstyle newsletter!

Tym samym wyrażasz zgodę na otrzymanie informacji marketingowych z devstyle.pl (doh...). Powered by ConvertKit
Notify of
Łukasz Błoszyk
Łukasz Błoszyk

Tutorial idzie w równie dobrym kierunku jak Goalng. Gratuluję talentu prostego przekazywania wiedzy.
Drobna uwaga: nie działa ostatni link do play.golang.org

Moja książka

Facebook

Zobacz również