Jak fungují Go rutiny - 2017-01-05 11:17:19

Dnes si povíme něco o Go rutinách. Všichni víme, že se používají, pokud chceme pracovat paralelně. Všichni určitě i víme, že Go rutiny nejsou thready (vlákna). Co tedy jsou Go rutiny a proč se používají?

Prvně, proč Go nepoužívá vlákna? Go vlákna používá, ale nepoužívá je 1:1 ke Go rutinám. Vlákno, jakkoliv se používají často, je má svoji režii. Režii na úrovni operačního systému (je to OS, kdo vlákna vytváří), režii na úrovni správy (je potřeba vlákna časovat a přepínat) a režii na úrovni paměti a registrů procesoru (je potřeba při přepínání vlákna ukládat prakticky všechny registry procesoru). Jak je zřejmé, pokud bychom chtěli mít tisíce Go rutin, tak by režie OS byla natolik veliká, že by se systém zhroutil.

Něco málo o pointerech - 2016-11-07 16:36:40

Dnes jsem si uvědomil jednu věc. V Go se to množí pointery, ale vlastně mnozí čtenáři tohoto blogu, kteří přicházejí ke Go ze světa JavaScriptu, Javy a dalších jazyků bez pointerů (v Česku známé také jako ukazatele), mohou být mírně zmatení, o čem to tu stále hovořím.

Než se pustím do dalších příkladů, tak jen ve zkratce pro znalce C a podobných jazyků, které pointery mají. V Go se vždy přenášejí parametry hodnotou. A to včetně hodnoty pointerů. Rozumíme si :-)

Chyby se stacktrace v #Go - 2016-11-03 11:27:03

Snad každý kdo přichází do světa Go ze světa Javy se diví, proč chyby v Go nemají stacktrace. Vždyť přeci chci vědět kde se chyba stala. A mají pravdu, standardní chyby v Go stacktrace nemají. Ale to není proto, že by autoři Go byli snad sadisti, co se vyžívají ve zmatení uživatelů jazyka. Je to proto, že v Go jsou chyby jen interfacy. Tzn. cokoliv co implementuje interface error je automaticky chybou. A vzhledem k tomu, že interface error má jen jednu funkci Error() string, tak je jeho implementace více než jednoduchá.

Objektové programování vs. #Golang - 2016-10-24 19:15:30

Dnes se podíváme na Go tak trochu filozoficky. Je, nebo není Go objektový jazyk, jak v tomto smyslu vypadá jeho srovnání se v současnosti nejpopulárnějším jazykem Java?

Go je opravdu tak trochu jako chytrá horákyně. Je funkcionální, ale ne zcela, je objektový, ale ne zcela. Než začne polemizovat o objektovosti Go, pojďme si připomenout, co dělá jazyk objektovým.

  • Třídy a objekty. Vše jsou objekty a objekty jsou instance tříd.
  • Zapouzdření. Data a operace nad daty jedno jsou.
  • Dědičnost. Třídy dědí svoje vlastnosti a potomek třídy je specializací svého rodiče.
  • Polymorfismus. Potomek dovede nahradit svého předka.
  • Přetěžování. Metoda může mít stejné jméno, ale jiné parametry.

Nuže. Go nemá třídy a objekty. Má ovšem struktury a funkce, které nad nimi operují, tzv. přijímače (receivers). Jelikož volání přijímače nad strukturou se označuje operátorem tečky, tak to v kódu vypadá stejně, jako např. v Javě.

Zjištění, jestli mapa obsahuje klíč - 2016-10-20 08:05:29

Každý potřebujeme čas od času zjistit, jestli je v mapě položka pod daným klíčem. V Go se to dělá velmi jednoduše.

	mapa := map[string]string{
		"položka1": "hodnota1",
	}
	if hodnota1, ok := mapa["položka1"]; ok {
		fmt.Printf("Hurá, mapa má klíč 'položka1': [%s]\n", hodnota1)
	}
	if hodnota2, ok := mapa["položka2"]; !ok {
		fmt.Printf("Bohužel, klíč 'položka2' není v mapě. Posuďte sami: [%#v], [%s]", mapa, hodnota2)
	}

Mimochodem, podobný postup se používá i v situaci, kdy si chcete ověřit typ proměnné.

	cokoliv := interface{}(1)
	if _, ok := cokoliv.(int); ok {
		fmt.Println("Sláva, cokoliv je int!")
	}
	if _, ok := cokoliv.(string); ok {
		fmt.Println("Sláva, cokoliv je string!")
	} else {
		fmt.Println("Bohužel cokoliv není string")
	}

Pracujeme s poli - 2016-10-17 11:27:00

Práce s poli patří k základům prakticky všeho. Pokud mám něčeho více jak jedna, tak se z toho stává pole. Běžně rozlišujeme tři typy polí:

  • obyčejné pole. V Go se deklaruje jako [n]T např.
   pole := [10]int

Všimněte si, že pole je typu [10]int. Tzn. velikost pole se nedá změnit. Pokud tedy předem víte, kolik prvků potřebujete a nechcete aby se to dalo změnit, pak je pole právě pro vás.

  • seznam. V Go se mu říká slice. Deklaruje se jako []T např. []int. Pokud chcete, můžete si u něj nastavit jeho počáteční kapacitu. Ovšem nikoliv při deklaraci, ale při inicializaci. Tedy např.
   seznam := make([]int, 10) // počáteční velikost pole je 10
  • množina. Mnoho jazyků přímo podporuje množiny, anlicky set. Go mezi takové jazyky nepatří, a tak musíte vzít za vděk nějakou knihovnou , která tuto funkcionalitu nabízí. Jen pro přesnost, množiny nejsou setříděné a neumožňují duplikáty.

Teď nejběžnějši operace nad poli, nebo slicy. Prvně si pole vytvoříme.

Větvení podle typu proměnné v #Golang - 2016-10-13 05:34:53

Někdy je potřeba si větvit program podle toho, jakého je proměnná typu. Typický příklad je interface{}. Jelikož se jedná o prázdný interface, tak jím může být cokoliv. Co když ale chcete jinak pracovat s int a jinak se string?

Následující příklad vám to ukáže.

proměnná := inteface{}(1) // přetypujeme int 1 na interface{}
switch proměnná.(type) { // podle typu proměnné
case int:
	fmt.Println("Je to int!") 
default:
	printString("Je to záhada")     
}

Jak vidno, prosté.

#Golang a multithreading - 2016-10-09 07:19:14

Tento článek jsem si nechával na slavnostní chvíle a ta zrovna přišla. Dnes si povíme o to paralelismu v Go.

V první řadě, co je to multithreading? Je to schopnost programu, dělat několik věcí najednou. Tedy například stáhnout stránku a číst z terminálu. Řeknete si, to přeci není problém, jen co uživatel stiskne tlačítko, tak prostě na konzoli vypíšu co, napsal. Třeba následovně.

   fmt.Print("Napiš něco: ")
   var input string
   fmt.Scanln(&input)
   fmt.Println(input)
   resp, _ := http.Get("http://www.google.cz/")
   _, err := io.Copy(os.Stdout, resp.Body)
   resp.Body.Close()

Samozřejmě to takhle jde, ale je to když budete chtít ještě během toho vypisovat např. aktuální čas? Nebo ukazovat, jak píše jiný uživatel na jiném počítači. Nakonec skončíte u nějaké podobné smyčky.

#Golang a přístup k databázi - 2016-09-27 05:31:55

V dnešní době nad neexistuje aplikace, která by nepřistupovala do databáze. Samozřejmě si můžeme ukládat data do souboru a mnohdy je to i efektivnější řešení, ale databáze nám luxusně umožní data ukládat a načítat a nestarat se přitom o detaily. V dnešní době rozdělujeme databáze do 2 proudů.

  • SQL databáze (nebo také relační databáze) - tedy databáze, kde jsou data ukládána jako relace mezi entitami. Většina z nich také garantuje ACID (atomičnost operací, konzistenci stav, integritu dat a durabilitu uložení). Mezi nejznámější patři MySql, PostgreSQL, Oracle, MS SQL Server atd.
  • NoSQL databáze - tedy databáze, které nevyžadují striktní schéma (ad hoc ukládání dat) místo ACID používají BASE (pouze základní dostupnost, měnící se (měkký) stav a eventuální konzistenci) - což samo osobě je slovní hříčka - prostě kyselost a zásaditost :-). Představily jsou MongoDB, Redis, Apache Cassandra, ElesticSearch apod.

Dnes si povíme, jak přistupovat k SQL databázím. Už proto, že Go tyto databáze standardizuje, na rozdíl od NoSQL, kde standard není.

Testujeme v #Golang (část 2) - 2016-09-24 11:56:57

V první části povídání o testování jsme si ukázali vcelku jednoduchý test a spustili jsme si jej.

Jedním z požadavků na testování je, aby testy doběhly co nejdříve. Je to proto, že chceme mít smyčku zpětné vazby co nejkratší. Nikdo nestojí o to, aby čekal více jak minutu na informaci, že je všechno v pořádku. Ale pak se naskytuje otázka - co v případě, že test závisí na něčem pomalém. Třeba databázi. Nebo volání externí služby přes HTTP. V tom případě tu máme celou plejádu možností a podíváme se na ně.