Porovnání jazyků založených na C - 2016-12-09 07:37:02

Na serveru eev.ee vyšel zajímavý článek na téma programovacích jazyků. Všímá si především “dědictví”, které si jazyky odnáší od svého prapředka C.

Řekl bych, že Go si vede velmi dobře. Samozřejmě že není ideální, což je dané také tím, že jazyk lze hodnotit pouze subjektivně, ale vlastnosti jako vícenásobné návratové hodnoty, switch bez break apod. autora zaujali. Posuďte sami!

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á.

if-else-if-else v #Go - 2016-11-02 08:37:54

Ve většině jazyků z rodiny C se větvění provádí pomocí if-else. Klasicky to funguje (např. v Go) takto.

if cosi > dalsiCosi {
   log.Println("cosi je větší než dalsiCosi.")
} else {
   log.Println("cos je menší než dalsiCosi.")
}

Takto to funguje dobře. Co když ale chceme naspat něco většího?

if cosi > dalsiCosi && time.Weekday() == time.Monday {
   log.Println("Je pondělí a cosi je větší než dalsiCosi.")
} else if cosi > dalsiCosi && time.Weekday() == time.Tuesday  {
   log.Println("Je úterý a cosi je větší než dalsiCosi.")   
} else {
   log.Println("Není pondělí a úterý, nebo cosi je menší než dalsiCosi, nebo tak něco v tom smyslu.")
}

Go ovšem nabízí tuto variantu namísto sestavy if-else-if-else.

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.

Bleskovka o ukazatelých na interface - 2016-09-30 11:00:50

Dnes si dáme první bleskovou zprávu.

### Nepoužívejte v kódu ukazatel (pointer) na interface.

Důvod.

Jakákoliv struktura, která implementuje interface, jej implementuje jak jako samotná struktura, tak jako ukazatel na strukturu.

Jen si musíte dát pozor na příjemce (receivery). Pokud příjemce předpokládá ukazatel (pointer), tak musíte volat daný příjemce na ukazateli. V následujícím příkladu je vidět, jak příjemce implementuje funkci Funkce na ukazateli a tím pádem je potřeba použít k jeho volání iface1 = &Secti{}. Tedy dereferencovat ukazatel na strukturu Secti.