Golang a kryptografie - 2017-07-18 17:47:50

Dnes si povíme něco o tom, jak funguje kryptografie v Go. Go jako (relativně) nový programovací je v této oblasti daleko a podporuje prakticky všechny možné šifry a řešení. Co je ale na osvěžující je fakt, že Go se stále snaží dělat věci jednoduše, takže na rozdíl od jiných nejmenovaných jazyků se zde nesetkáme s milionem interfaců a object factory.

Kryptografie je opravdu obsáhlý prostor, takže my si ukážeme použitelné a praktické implementace kryptografie.

Generics v Golang - 2017-06-21 12:59:02

Poslední dobou je možné sledovat na poli jazyka Go zajímavou bitvu. Jak se blíží Go verze 2.0 (a pozor, po 1.9 může klidně přijít 1.10), tak se začínají objevovat nápady typu “přidejme do jazyka generické typy”. Nejdřív jsem i já stál na generické straně barikády, ale musím uznat, že postupem času se spíš kloním ke skupině genericsů méně, nebo třeba vůbec ne. Možná bych chtěl na toto téma rozvířit debatu, takže zde je můj pohled na věc.

Výčtové typy - 2017-05-12 07:35:51

Určitě to víte - Go nepodporuje výčtové typy - tedy enum. Go umí numerické sekvence pomocí iota, ale to se opravdu nerovná enumu. Když jsem se nedávno na projektu vrátil ke staršímu kódu (který jsem napsal), tak jsem si uvědomil, že v jedné chvíli jsem vlastně použil něco, co může fungovat jako náhrada za výčty. No posuďte sami.

package main

import (
	"fmt"
)

type AnswerEnum struct {
	string
}

var (
	Yes AnswerEnum = AnswerEnum{"Yes"}
	No  AnswerEnum = AnswerEnum{"No"}
)

func main() {
	cond := []AnswerEnum{AnswerEnum{"Yes"}, AnswerEnum{"No"}}
	for i, answer := range cond {
		switch answer {
		case Yes:
			fmt.Println("na indexu", i, "je hodnota", Yes.string)
		case No:
			fmt.Println("na indexu", i, "je hodnota", No.string)
		}
	}
}

To co se zde děje je zjevné. Nejdříve si vytvoříme nový typ typu AnswerEnum, který je kompozicí typu string. Jelikož lze stringy mezi sebou porovnávat, tak je pak možné použít tyto hodnoty v bloku switch.

Jak si udělat transakční databázi - 2017-04-13 12:29:57

Určitě jste si toho všimli - Go má (podle mě) velmi dobrou podporu relačních databází. A to včetně věcí typu transakce. Pokud chcete ovšem transparentně přistupovat k databázi tak, aby vám bylo jedno, jestli dotaz provádíte v rámci transakce, nebo mimo ni, tak máte problém. Standardní API totiž rozlišuje mezi přímým dotazem do databáze a mezi dotazem v rámci transakce.

Abychom tuto “podružnost” eliminovali, a také si ukázali jak si udělat abstrakční vrstvu nad konkrétní implementací, tak si napíšeme zaobalení (wrapper) databáze. Bude mít stejné funkce na provádění základních dotazů jako má standardní Go API.

Rozdíl mezi kanálem prázdné struktury a kanálem prázdného interfacu - 2017-04-02 06:35:51

Mnohdy si člověk myslí, že něco je naprosto jasné. Tedy až do okamžiku, kdy dostanete dotaz, který vám ukáže, že nejasnosti jsou na každém rohu.

Zrovna teď se mně kolega ptal, jaký je rozdíl mezi kanálem prázdné struktury a kanálem prázdného interfacu.

Odpověď je, že zásadní.

Prázdná struktura jako typ má omezené, ale legální použití. Sama o sobě nemůže nést data (nemá žádné pole, kam se dalo cokoliv uložit), ale už její přítomnost nám umožňuje ji použít na místech, kde prostě potřebujeme “nějakou” proměnnou. Jako další místo použití vidím jako možnost zavěsit na tuto strukturu receivera (příjemce) a použít takto vytvořenou proměnnou jako parametr typu interface.

Předávání polí (sliců) hodnotou a na co si dát pozor - 2017-03-14 19:47:03

Když jsme se bavili o slicech tak nezazněla jedna podstatná informace. Jak vlastně vypadá taková struktura slicu.

Vytvořme si tedy slice.

package main

import "fmt"

func main() {
	slice := []int{}
	fmt.Println("délka:", len(slice))
	fmt.Println("maximální délka:", cap(slice))
}

Délka i maximální délka jsou shodné, tedy 0.

Teď si k danému slicu přidejme jedno položku a zkusme to znovu.

package main

import "fmt"

func main() {
	slice := []int{}
	slice = append(slice, 0)
	fmt.Println("délka:", len(slice))
	fmt.Println("maximální délka:", cap(slice))
}

Tentokrát je délka 1 a maximální délka je 2. Co to znamená? append nám nejen přidal do pole jednu položku, ale také nám nechal ve slicu “fuku” pro jedno další číslo. Tzn. pokud přidáme další položku, tak nám append nemusí zvětšovat pole, prostě přidá položku na konec již alokovaného pole.

Duck typing v #GO - 2017-01-25 15:36:16

Možná už jste někdy slyšeli termín “duck typing”. Pro ty co náhodou ne, tak jen krátce uvedu, že se jedná o aplikaci známého pořekadla “kváká to jako kachna, vypadá to jako kachna, tak je to kachna”.

Představte si tyto dva typy.

type Člověk struct {
   Jméno string
}

type Mazlíček struct {
   Jméno string
}

Je jasné, že se jedné o dva typy. Člověk a Mazlíček. Oba jsou ovšem stejné - mají (sice jen jedno) pole - Jméno.

Jak na `Cannot read property 'substring' of undefined` ve VS Code - 2017-01-10 10:38:06

Pokud jako já používáte Visual Studio Code pro práci s projekty v Go tak jsme možná narazili na problém při formátování zdrojových souborů (standardně cmd + alt + L na MacOs). Místo vytouženého zformátování se zobrazí

Cannot read property 'substring' of undefined

Nuže problém je v chybějící prázdné řádce na konci souboru. Stačí tedy jen přidat na konec souboru jednu prázdnou řádku a problém je vyřešen.

Např.

package main

func main () {
....
} // následuje prázdná řádka

Více na Githubu.

Dnešní bleskovka - sady (množiny) v Golang - 2017-01-10 08:48:24

Dnes opět jen telegraficky. Go nepodporuje sady (množiny) a tak tu máme drobnou obezličku, jak si takovou sadu vytvořit. Využijeme toho, že mapy mají unikátní klíče a jsou netříděné. Že to zní povědomě? Ano! Vždyť to je přece množina.

Takže než abychom si mazali ruce nějakým bastlením kódu si uděláme např. toto:

package main

import (
	"fmt"
)

func main() {
	množinaIntů := map[int]struct{}{}
	množinaIntů[2] = struct{}{}
	množinaIntů[1] = struct{}{}
	množinaIntů[3] = struct{}{}
	množinaIntů[4] = struct{}{}
	množinaIntů[1] = struct{}{}
	// jen si mapu prosvištíme, ať víme co v ní je
        for key := range množinaIntů {
		fmt.Println("Položka množiny:", key)
	}
	// zjištění jestli množina obsahuje položku
	if _, ok := množinaIntů[1]; ok {
		fmt.Println("Množina obsahuje položku 1.")
	}
}

Padl tu dotaz, proč je použit typ map[int]struct{}. Tedy mapu s klíčem int a položkami typu prázdná struktura. Důvod je prostý, prázdná struktura zabírá (logicky) v paměti 0 bajtů.

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.