Z Go idę trochę inaczej niż z Elixir, więc posty będą pojawiać się dużo rzadziej. Kilka tygodni temu zacząłem swoją przygodę z językiem Go bo tak :) Zarówno Go jak i Elixir chciałem się nauczyć więc nawet nie szukałem innego języka, wziąłem kolejny z listy i do zabawy. Dziś więc trochę o tych moich pierwszych zabawach i spostrzeżeniach – to co mi się podoba do tej pory a to co mi się nie podoba, można nazwać to Part 1 bo będzie tego pewnie więcej.

Oczywiście, Go Lang jak każdy szanujący się ostatnio język jak i odłam ćwiczeń czy też sekta używa własnego języka do opisywania tego co się dzieje. Ja jestem słaby w nazwach takich więc będę używał nazw mi znanych – na przykład public i private zamiast eksportowanie i nieeksportowanie. Za co z góry przepraszam wszystkich przyszłych i teraźniejszych purystów Go Lang :)

Import (słabe, spekulacyjnie)

Krótko, bardzo jakoś do mnie to nie przemawia import – źle mi się kojarzy z Java. Jakoś tak odstraszająco ;) Ogólnie jest to po prostu taki using C#, import JavaScriptowy czy też Javowy czy require z Elixir. Coś co daje nam funkcjonalność danej biblioteki, modułu w naszym własnym kodzie.

Paczki możemy zaimportować na dwa sposoby:

import "pacakge1"
import "pacakge2"

Lub:

import (
    "package1"
    "package2"
)

Małe i wielkie litery (fajne)

Mają znaczenie w Go. Jako konwencje przyjęło się, że metody zaczynające się od małych liter są metodami ograniczonymi do danej paczki, pliku. Tak zwane są one metodami prywatnymi. Wszystkie metody z dużej litery są metodami publicznymi widzianymi zewnątrz.

Osobiście mi się to podoba, sam taką politykę stosuję w C# od lat a rygorystycznie już od roku i jest mi z tym dobrze. Tutaj po prostu nie muszę pisać priv/public i reszta śmiga, jak powinna :)

Deklaracja typu danych (słabe)

Drażni mnie to, że typ danych podaje się na końcu deklaracji czy też zmiennej:

func sum(x int, y int) {

}

Czy też jak mam określić wartość zwracaną:

func sum(x int, y int) int {

}

Albo tablicę:

var x [2]int

Argh! Serio nie mogę się do tego przyzwyczaić, musze chyba więcej czasu z Go spędzić :) a tak to cały czas się łapie, że piszę int x

Nazwa zmiennych zwracanych danych (so-so)

W go możemy określić nazwy parametrów które będziemy zwracać:

func sqr(x int) z int {
   z = x * x
   return
}

To co tutaj zrobiliśmy to uzyskaliśmy zmienną z która istnieje w naszej metodzie i która domyślnie zostanie zwrócona jak zastosujemy pusty return.

Jest to nawet ok, ale przy założeniu, że funkcje nie są długie. Jeżeli się zastanowić to w C# też dosć często piszę kod:

public bool DoSmth()
{
     var result = false;
     // ...
     return result;
}

Więc i tak deklaruje coś na górze. Jedynie trochę zamieszania daje mi ten return bez niczego.

Przypisywanie zmiennych podczas deklaracji (so-so)

Normalnie jak tworzymy zmienne to albo podajemy ich typ, albo oczekujemy, że kompilator to zgadnie/w runtime zostanie to zweryfikowane. Czyli:

// c#
var x = 10;
int z = 10;
int a, b, c;

W Go to już trochę inaczej wygląda. Po pierwsze wiemy, że deklaracja typu jest na końcu, a więc zapis już bardziej wygląda na:

x int = 10

Tylko, że to x musi jakoś powstać… zostać stworzone. W tym celu musimy dodać var:

var x int = 10

Nie jest to jakoś miłe dla oka, trochę się to też dla mnie źle czyta. Na szczęście można stosować trzy skróty które mogą trochę pomóc.

Skrót pierwszy:

var x, y int = 1,2

Czyli deklaracje wielu zmiennych z przypisaniem tego samego typu. Kod powyżej przypisze 1 do x i 2 do y. Jednak dla mnie czytelność tego jest gorsza niż pojedynczego zapisu.

Skrót drugi to:

var x, y, z = 1, false, "tak"

Czyli przypisanie wartości do zmiennych bez podania typu – tutaj typ zostanie zgadnięty tak jak to jest w C#. Fajna sprawa. Działa też bardzo sprawnie. Minusem jest to, że jak będziemy tego nadużywać to będzie się ciężko połapać kto ma jaką wartość i jakiego typu – po prostu nie jest to super czytelne.

Istnieje jeszcze trzeci skrót, :=

x := 10

Który powoduje, że nawet var nie jest nam już potrzebne i jest to chyba opcja, którą najczęściej wykorzystuje.

Brak średników, nie zawsze nawiasy (so-so)

Tutaj po prostu się gubię, raz muszę dać nawias, raz nie mogę go mieć, a czasami aż by się chciało wstawić średnik lub przecinek ale nie, nie wolno.

Dla przykładu pętla for nie mają nawiasów, if też nie ma, ale func już ma.

Mała niedogodność, ale do przeżycia.

Factory (fajne)

Czasami możemy skorzystać z czegoś co ludzie nazywają factory. Pamiętacie jak z importami zrobiliśmy import ()? Tak samo możemy zrobić z var (), przez co możemy zadeklarować kilka zmiennych na raz:

var (
   zmienna1 int = 10
   zmienna2 string = "hello"
)

Pętla for która jest czymś więcej (so-so)

Pętle, w elixir ich w ogóle nie ma, w C# mamy ich pod dostatkiem w Go mamy for które może działać jak standardowy for i jak while.

Zarówno to jest poprawne:

for i := 0; i < 10; i++ {

}

Jak i:

for {

}

Deklaracja zmiennej w if (so-so)

Dziwne to, ale możemy stworzyć zmienną w if:

if i := 5; i < 10 {

}

Taka zmienna ma zakres bloku if i bloku else.

Switch (nawet spoko)

Switch różni się dwoma rzeczami, pierwsza rzecz jest taka, że samo polecenie:

i := 10

swtich {
    case i < 10:
        fmt.Print("test")
   default:
       fmr.Print("d")
}

Jest potraktowane tak jakbyśmy do switch przekazali wartość true. Czyli dosłownie if-else-if czy takie cond w elixir (case ma pattern matching a w go za bardzo go nie ma).

Drugi jest taki, że domyślne każdy case kończy i wychodzi ze switch (break nie jest potrzebny). Jeżeli zaś chcemy by przeskoczył do kolejnego case, to musimy dodać polecenie: fallthrough na końcu każdego case oprócz ostatniego.

Podsumowanie

To tyle takiego szybkiego podsumowania. Tego jest jeszcze trochę ale zbieram dane i zastanawiam się czy to mnie drażni i przeszkadza czy nie. Więc lista na pewno jeszcze nie jest skończona w szczególności, że dopiero zaczynam zabawę jak i zmieniam swój tok myślenia by zacząć móc pisać trochę bardziej swobodnie w języku go. W elixir też mi kilka rzeczy przeszkadzało, ale im dłużej pisałem tym mniej mi one przeszkadzały :) Może więc tutaj będzie tak samo?

A więc do następnego!