Do czego naprawdę nadaje się język Go?

W ciągu ponad dziewięciu lat spędzonych na wolności, język Go firmy Google, znany również jako Golang - z wersją 1.13 we wrześniu 2019 r. - ewoluował z ciekawości dla maniaków alfa do sprawdzonego w boju języka programowania, który stoi za niektórymi z najważniejszych na świecie projekty skoncentrowane na chmurze. 

Dlaczego Go wybrali twórcy takich projektów jak Docker i Kubernetes? Jakie są definiujące cechy Go, czym różni się od innych języków programowania i jakie rodzaje projektów są najbardziej odpowiednie do tworzenia? W tym artykule omówimy zestaw funkcji Go, optymalne przypadki użycia, pominięcia i ograniczenia języka oraz dokąd zmierza Go.

Język Go jest mały i prosty

Go, lub Golang, jak to często się nazywa, zostało opracowane przez pracowników Google - głównie długoletniego guru ds. Uniksów i wybitnego inżyniera Google, Roba Pike'a - ale nie jest to ściśle mówiąc „projekt Google”. Zamiast tego Go jest rozwijany jako projekt open source kierowany przez społeczność, kierowany przez przywódców, którzy mają silne opinie na temat tego, jak powinno się używać Go i w jakim kierunku powinien podążać język.

Go ma być łatwa do nauczenia się, prosta w obsłudze i łatwa do odczytania przez innych programistów. Go nie ma dużego zestawu funkcji, zwłaszcza w porównaniu z językami takimi jak C ++. Go przypomina C w swojej składni, co czyni go stosunkowo łatwym do nauki dla długoletnich programistów C. To powiedziawszy, wiele funkcji Go, zwłaszcza jego współbieżność i funkcje programowania funkcjonalnego, nawiązuje do języków takich jak Erlang.

Jako język podobny do języka C do tworzenia i utrzymywania wszelkiego rodzaju aplikacji korporacyjnych międzyplatformowych, Go ma wiele wspólnego z Javą. Aby umożliwić szybkie tworzenie kodu, który może działać w dowolnym miejscu, można narysować paralelę między Go i Pythonem, chociaż różnice są znacznie większe niż podobieństwa.

Język Go ma coś dla każdego

Dokumentacja Go opisuje Go jako „szybki, statycznie wpisywany, skompilowany język, który sprawia wrażenie dynamicznie wpisywanego, interpretowanego języka”. Nawet duży program Go skompiluje się w ciągu kilku sekund. Ponadto Go pozwala uniknąć większości narzutów związanych z plikami dołączanymi w stylu C. i bibliotekami.

Go ułatwia życie programistom na wiele sposobów:

  • Wygoda.  Go porównuje się do języków skryptowych, takich jak Python, pod względem możliwości zaspokojenia wielu typowych potrzeb programistycznych. Niektóre z tych funkcji są wbudowane w sam język, na przykład „goroutyny” zapewniające współbieżność i zachowanie wątkowe, podczas gdy dodatkowe możliwości są dostępne w standardowych pakietach bibliotek Go, takich jak pakiet HTTP Go. Podobnie jak Python, Go zapewnia funkcje automatycznego zarządzania pamięcią, w tym zbieranie elementów bezużytecznych.

    W przeciwieństwie do języków skryptowych, takich jak Python, kod Go kompiluje się do szybko działającego natywnego pliku binarnego. W przeciwieństwie do C czy C ++, Go kompiluje się niezwykle szybko - wystarczająco szybko, aby praca z Go przypominała bardziej pracę z językiem skryptowym niż językiem kompilowanym. Co więcej, system kompilacji Go jest mniej złożony niż systemy innych języków kompilowanych. Zbudowanie i uruchomienie projektu w Go wymaga kilku kroków i niewielkiej księgowości.

  • Prędkość.  Pliki binarne Go działają wolniej niż ich odpowiedniki w C, ale różnica w szybkości jest pomijalna w przypadku większości aplikacji. Wydajność Go jest tak dobra jak C dla większości prac i ogólnie dużo szybsza niż inne języki znane z szybkości tworzenia (np. JavaScript, Python i Ruby).
  • Ruchliwość.  Pliki wykonywalne utworzone za pomocą łańcucha narzędzi Go mogą działać samodzielnie, bez domyślnych zależności zewnętrznych. Łańcuch narzędzi Go jest dostępny dla wielu różnych systemów operacyjnych i platform sprzętowych i może być używany do kompilowania plików binarnych na różnych platformach.
  • Interoperacyjność.  Go zapewnia wszystkie powyższe rozwiązania bez poświęcania dostępu do podstawowego systemu. Programy Go mogą komunikować się z zewnętrznymi bibliotekami C lub wykonywać natywne wywołania systemowe. Na przykład w Dockerze Go łączy się z niskopoziomowymi funkcjami Linuksa, grupami cgroup i przestrzeniami nazw, aby pracować z magią kontenerów.
  • Wsparcie.  Łańcuch narzędzi Go jest dostępny bezpłatnie jako plik binarny dla systemu Linux, MacOS lub Windows lub jako kontener Docker. Go jest domyślnie dołączone do wielu popularnych dystrybucji Linuksa, takich jak Red Hat Enterprise Linux i Fedora, co nieco ułatwia wdrażanie źródła Go na tych platformach. Wsparcie dla Go jest również silne w wielu środowiskach programistycznych innych firm, od Microsoft Visual Studio Code do ActiveState's Komodo IDE.

Gdzie język Go działa najlepiej

Żaden język nie jest dostosowany do każdej pracy, ale niektóre języki nadają się do większej liczby zawodów niż inne.

Go świeci najjaśniej przy tworzeniu następujących typów aplikacji:

  • Rozproszone usługi sieciowe. Aplikacje sieciowe żyją i umierają dzięki współbieżności, a natywne funkcje współbieżności Go - głównie gorutyny i kanały - doskonale nadają się do takiej pracy. W związku z tym wiele projektów Go dotyczy sieci, funkcji rozproszonych i usług w chmurze: interfejsów API, serwerów internetowych, minimalnych struktur dla aplikacji internetowych i tym podobnych.
  • Rozwój natywny dla chmury. Współbieżność i funkcje sieciowe Go oraz wysoki stopień przenośności sprawiają, że doskonale nadaje się do tworzenia aplikacji natywnych dla chmury. W rzeczywistości Go został użyty do zbudowania kilku kamieni węgielnych przetwarzania natywnego dla chmury, w tym Docker, Kubernetes i Istio.
  • Zamienniki dla istniejącej infrastruktury. Znaczna część oprogramowania, na którym polegamy w zakresie infrastruktury internetowej, starzeje się i jest atakowana przez exploity. Przepisanie takich rzeczy w Go zapewnia wiele korzyści - lepsze bezpieczeństwo pamięci, łatwiejsze wdrażanie na wielu platformach i czystą bazę kodu w celu promowania przyszłej konserwacji. Nowy serwer SSH o nazwie Teleport i nowa wersja Network Time Protocol są zapisywane w Go i oferowane jako zamienniki ich tradycyjnych odpowiedników.
  • Programy narzędziowe i samodzielne narzędzia. Programy Go kompilują się do plików binarnych z minimalnymi zależnościami zewnętrznymi. To sprawia, że ​​idealnie nadają się do tworzenia narzędzi i innych narzędzi, ponieważ uruchamiają się szybko i można je łatwo spakować do ponownej dystrybucji.

Ograniczenia językowe

Uparty zestaw funkcji Go przyciągnął zarówno pochwały, jak i krytykę. Go został zaprojektowany tak, aby był mały i łatwy do zrozumienia, a niektóre funkcje zostały celowo pominięte. W rezultacie niektóre funkcje, które są powszechne w innych językach, po prostu nie są dostępne w Go - celowo.

Jedną z takich funkcji są typy ogólne, które pozwalają funkcji akceptować wiele różnych typów zmiennych. Go nie zawiera typów ogólnych, a zarządcy języka sprzeciwiają się ich dodawaniu, uznając, że typy rodzajowe zagroziłyby prostocie języka. Można obejść to ograniczenie, ale wielu programistów nadal nie może się doczekać, aby w jakiś sposób dodano do Go generics. Zgłoszono co najmniej jedną propozycję wdrożenia leków generycznych w Go, ale nic nie zostało ustalone.

Kolejną wadą Go to rozmiar generowanych plików binarnych. Pliki binarne Go są domyślnie kompilowane statycznie, co oznacza, że ​​wszystko, co jest potrzebne w czasie wykonywania, jest zawarte w obrazie binarnym. Takie podejście upraszcza proces tworzenia i wdrażania, ale kosztem prostego „Witaj, świecie!” waży około 1,5 MB w 64-bitowym systemie Windows. Zespół Go pracował nad zmniejszeniem rozmiaru tych plików binarnych z każdym kolejnym wydaniem. Możliwe jest również zmniejszenie plików binarnych Go za pomocą kompresji lub przez usunięcie informacji debugowania Go. Ta ostatnia opcja może działać lepiej w przypadku autonomicznych aplikacji rozproszonych niż w przypadku usług w chmurze lub usług sieciowych, w których posiadanie informacji debugowania jest przydatne w przypadku awarii usługi.

Jeszcze inną reklamowaną cechę Go, automatyczne zarządzanie pamięcią, można uznać za wadę, ponieważ czyszczenie pamięci wymaga pewnego obciążenia przetwarzania. Z założenia Go nie zapewnia ręcznego zarządzania pamięcią, a zbieranie elementów bezużytecznych w Go jest krytykowane za to, że nie radzi sobie dobrze z rodzajami obciążeń pamięci, które pojawiają się w aplikacjach korporacyjnych. Z drugiej strony, Go 1.8 wprowadza wiele ulepszeń do zarządzania pamięcią i czyszczenia pamięci, które zmniejszają czas opóźnienia. Oczywiście programiści Go mają możliwość ręcznego przydzielania pamięci w rozszerzeniu C lub za pośrednictwem biblioteki ręcznego zarządzania pamięcią innej firmy.

Kultura oprogramowania związana z budowaniem bogatych GUI dla aplikacji Go, takich jak te w aplikacjach komputerowych, jest nadal rozproszona.

Większość aplikacji Go to narzędzia wiersza poleceń lub usługi sieciowe. To powiedziawszy, różne projekty pracują nad wprowadzeniem bogatych GUI dla aplikacji Go. Istnieją powiązania dla frameworków GTK i GTK3. Inny projekt ma na celu zapewnienie interfejsów użytkownika natywnych dla platformy, chociaż opierają się one na powiązaniach języka C i nie są napisane w czystym Go. Użytkownicy systemu Windows mogą wypróbować spacer. Ale w tej przestrzeni nie pojawił się żaden wyraźny zwycięzca ani bezpieczny długoterminowy zakład, a niektóre projekty, takie jak próba Google zbudowania wieloplatformowej biblioteki GUI, odeszły na marne. Ponadto, ponieważ projekt Go jest niezależny od platformy, jest mało prawdopodobne, aby którykolwiek z nich stał się częścią standardowego zestawu pakietów.

Chociaż Go może komunikować się z natywnymi funkcjami systemowymi, nie zostało zaprojektowane do tworzenia niskopoziomowych komponentów systemowych, takich jak jądra lub sterowniki urządzeń lub systemy wbudowane. W końcu środowisko uruchomieniowe Go i moduł odśmiecania pamięci dla aplikacji Go są zależne od bazowego systemu operacyjnego. (Deweloperzy zainteresowani nowatorskim językiem do tego rodzaju prac mogą zajrzeć do języka Rust.)

Idź na przyszłość językową

Następna faza rozwoju Go może być bardziej napędzana przez chęci i potrzeby jego bazy programistów, a opiekunowie Go zmieniają język, aby lepiej dostosować się do tej publiczności, zamiast tylko dawać uparty przykład. Innymi słowy, Go może zyskać funkcje, które pierwotnie nie były do ​​niego przeznaczone, na przykład generyczne.

Jest jasne, że programiści Golang chcą takich rzeczy. Ankieta przeprowadzona wśród użytkowników Go 2018 umieściła leki generyczne wśród trzech najważniejszych wyzwań na drodze do szerszego przyjęcia Go, wraz z lepszą zależnością i zarządzaniem pakietami. Istniejąca propozycja na GitHub dla leków generycznych pozostaje aktywna jako propozycja dla Go 2.x. Takie zmiany mogą pomóc Go zająć bardziej centralne miejsce w rozwoju przedsiębiorstwa, w którym obecnie królują Java, JavaScript i Python.

Nawet bez większych zmian możemy spodziewać się zwiększonego wykorzystania Go do projektów przebudowy infrastruktury, zgodnie z opisanymi powyżej zamiennikami SSH i NTP oraz w ramach projektów wielojęzycznych. 

Mnożyły się również wdrożenia innych firm łańcucha narzędzi Go. ActiveState's ActiveGo zapewnia komercyjnie obsługiwaną wersję języka Go, a zarówno projekty LLVM, jak i gccgo zapewniają implementacje Go na licencji open source za pośrednictwem alternatywnych łańcuchów narzędzi.

Wreszcie, Go posłużył również jako podstawa do opracowania zupełnie nowych języków, chociaż dwa przykłady tego zaprzestały aktywnego rozwoju. Jednym z przykładów był język Have, który usprawnił składnię Go, zaimplementował niektóre z tych samych koncepcji na swój własny sposób i przetransponował do Go w celu łatwego wykonania. Inny nieistniejący projekt, Oden, wykorzystał asembler i łańcuch narzędzi Go do skompilowania nowo zaprojektowanego języka, który czerpał dodatkową inspirację z języków takich jak Lisp i Haskell.

Ten ostatni zestaw projektów ilustruje jeden ze sposobów, w jakie każda innowacja IT staje się prawdziwie rewolucyjna - kiedy ludzie ją rozkładają i zmieniają jej przeznaczenie, znajdują zastosowania, których projektanci nigdy nie zamierzali. Przyszłość języka Go jako projektu, który można zhakować, dopiero się zaczyna. Ale jego przyszłość jako głównego języka programowania jest już zapewniona, z pewnością w chmurze, gdzie szybkość i prostota Go ułatwiają tworzenie skalowalnej infrastruktury, którą można utrzymać w dłuższej perspektywie.