abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
dnes 02:30 | Nová verze
Byla vydána verze 14.12.0 KDE Aplikací (KDE Applications). Většina z nich je založena na knihovnách KDE Platform 4. Některé, například Kate, KWrite nebo Konsole, jsou už ale založené na KDE Frameworks 5. Podrobnosti v kompletním seznamu změn a na stránce s dalšími informacemi. Před několika dny vyšly také knihovny KDE Frameworks 5.5.0 a prostředí KDE Plasma 5.1.2.
Ladislav Hagara | Komentářů: 14
dnes 02:30 | Bezpečnostní upozornění
Organizace ICANN se stala terčem spear phishingového útoku, při kterém útočníci získali přístup do několika zaměstnaneckých e-mailů. Následně získali administrátorský přístup také do aplikace "Centralized Zone Data System". Z tohoto důvodu byla hesla na účtech uživatelů CZDS deaktivována a uživatelé si musí požádat o reset hesla. Zároveň se uživatelům doporučuje provést změnu hesla i v dalších systémech, pokud někde používali stejné přihlašovací údaje. [CSIRT.CZ]
Ladislav Hagara | Komentářů: 7
včera 15:00 | Nová verze
Po ipfwadm, ipchains a iptables přichází nftables. Subsystém pro filtrování paketů nftables se v lednu dostal do Linuxu 3.13 (zprávička). Včera vyšla verze 0.4 balíku nftables. Nejnovější verze nftables a nástroje nft přináší například podporu Linuxu 3.18 a 3.19.
Ladislav Hagara | Komentářů: 0
včera 13:00 | IT novinky
Google na Google+ oznámil, že jeho Dokumenty, Tabulky a Prezentace nově otevřou také soubory ve třech hlavních ODF formátech (.odt, .ods a .odp).
Ladislav Hagara | Komentářů: 3
včera 11:30 | Zajímavý článek
Na serveru Hack A Day byl publikován článek o domácích počítačích za železnou oponou (Home Computers Behind The Iron Curtain). Martin Malý se zde věnuje počítačům jako JPR-1, Ondra, PMD 85, IQ 151 nebo Didaktik Gama.
Ladislav Hagara | Komentářů: 38
16.12. 23:57 | Nová verze
Po dvou letech vývoje vyšla nová verze desktopového prostředí Trinity (fork KDE3). Změnilo se značení verzí a nová verze je tedy R14.0.0 (a nikoli 3.5.14). Mimo jiné byla odstraněna závislost na HALu a přidána podpora network-manageru 0.9. K dispozici jsou zatím balíky pro Debian a Ubuntu, buildování balíků pro další distribuce teprve probíhá.
Hans1024 | Komentářů: 47
16.12. 23:56 | Zajímavý článek

Záznam z prednášky Architektúrou proti špagetám v podaní Tomáša Kulicha z cyklu Confused Coder, ktorá sa uskutočnila 2. decembra v SPOTe v Bratislave, je na svete.

… více »
Vacuumlabs | Komentářů: 1
16.12. 14:15 | Zajímavý projekt
Na blogu sdružení CZ.NIC byl představen Majordomo, nástroj vyvinutý jako reakce na kauzu chytrých televizí některých výrobců, které odesílají data o uživatelské aktivitě (zprávička). Cílem Majordomo je poskytnou uživateli nástroj, s jehož pomocí získá snadno přehled nad děním ve své lokální síti. Data z nástroje Majordomo nejsou odesílána k dalšímu zpracování.
Ladislav Hagara | Komentářů: 12
16.12. 07:00 | Nová verze
V únoru byl multiplatformní herní engine Godot uvolněn pod licencí MIT (zprávička). Po 10 měsících vývoje vyšla první stabilní verze 1.0. Přehled vlastností a tutoriály na stránkách herního enginu.
Ladislav Hagara | Komentářů: 5
15.12. 13:14 | Komunita
V Edici CZ.NIC vyšla kniha LibreOffice Writer – Praktický průvodce. Autorem je Vlastimil Ott. Kniha je ke stažení zcela zdarma nebo lze objednat tištěnou verzi za 399 Kč (připojení přes IPv4) nebo 349 Kč (připojení přes IPv6).
Ladislav Hagara | Komentářů: 45
Disketu jsem naposledy použil během
 (46%)
 (3%)
 (11%)
 (37%)
 (2%)
Celkem 1586 hlasů
 Komentářů: 54, poslední 9.12. 17:16
    Rozcestník
    Reklama
    Autoškola testy online Levný benzín

    Google Go v příkladech 1.

    18. 5. 2011 | Jan Mercl | Programování | 5074×

    Zahajujeme navazující seriál o programování v Go, tentokrát v příkladech. Ukázky se soustředí na malý (nebo jeden) okruh problémů a budou – i vzhledem k rozsahu článku/dílu seriálu – jen schematické.

    Na druhé straně každá ukázka je v době odevzdání (Go se již mění pomaleji, ale ke změnám stále dochází) kompletní program, který je možno přeložit (pokud neukazuje úmyslně nepřeložitelnou chybu). Novinkou, přinejmenším snad v článcích o Go na AbcLinuxu, je možnost si na Go doopravdy „sáhnout“ a to i bez instalace jeho distribuce. Na domácí stránce Go je už nějaký čas tzv. Go playground. V něm je možné, v rámci některých pochopitelných omezení, zadávat a upravovat zdrojový kód v Go, následně jej nechat na vzdáleném serveru přeložit/sestavit a v případě úspěchu i provést. Pokud výsledný program úspěšně doběhne ve svém časovém limitu, zobrazí Go playground i vše, co zapsal program napsal do svého standardního výstupu.

    Veškeré ukázky kódu jsou následovány odkazem, který příklad otevře v Go playgroundu. Tam je pak možné ukázku/program upravovat a nakonec klepnutím na tlačítko „COMPILE & RUN“ (nebo stiskem shift-enter) zkusit provést. Neověřoval jsem, ale předpokládám, že povolený Javascript bude nejspíše nutný. Pokud si „pískoviště“ zkusíte, může se Vám stát, že některá z dnešních ukázek bude hlásit timeout. Obvykle postačí ji v takovém případě zkusit provést ještě jednou, ale úspěch může záležet na zcela vnějších faktorech (možná dle okamžitého zatížení některého Google serveru), takže nic se v tomto směru nedá slíbit. Z diskuzí jinde pochází ještě jedna rada – někdy stačí v případě potíží (timeout provádění) jen pozměnit whitespace programu a tím ovlivnit použití kompilační cache playgroundu, která je v současné implementaci podezřelá, že je někdy příčinou problému.

    V době odevzdávání článku se navíc ještě našla nemilá chyba (nahlášená), která se projevuje ve Firefoxu a (zatím) znemožňuje použití Go playground z FF. Doufejme, že chyba bude do doby vyjití článku opravena.

    Obsah

    Odlož paniku, vzchop se a jdi (defer panic, recover and go)

    link

    Příklad 1.

    link
    package main 
    
    import "fmt"
    
    func f(x int, c chan string) { 
        defer func() { 
            if e := recover(); e != nil { 
                c <- fmt.Sprintf("f(%d): %s", x, e) 
            } 
        }() 
    
        if x == 2 { 
            panic("x == 2 není podporováno") 
        } 
    
        c <- fmt.Sprintf("f(%d) == %d", x, 2*x) 
    } 
    
    func main() { 
        c := make(chan string) 
        for i := 1; i <= 2; i++ { 
            go f(i, c) 
            defer fmt.Printf("(%d) %s\n", i, <-c) 
        } 
    } 
    

    Upravit/Spustit

    Výstup:

    (2) f(2): x == 2 není podporováno
    (1) f(1) == 2
    

    Klíčové slovo go spustí provádění dané funkce/funkčního literálu v nové gorutině (ř.22). Gorutina nemůže volajícímu přímo nic vrátit (ve smyslu funkční hodnoty), volající navíc pokračuje bez čekání na ukončení gorutiny. Pokud chceme s paralelně prováděnou gorutinou komunikovat, je standardním Go idiomem použití komunikačních kanálů. V ukázce je kanál vytvořen na ř.20, funkce f (ř.5) standardně tímto kanálem odpovídá, gorutina jej získala jako argument volání. Na ř.16 odpovídá normálně a na ř.8 při výjimce (k té za chvíli).

    Na ř.23 hlavní fuknce programu vypisuje výsledky vrácené gorutinami kanálem. V tomto případě pomocí odloženého příkazu klíčovým slovem defer (k němu opět za moment). Důležité je si uvědomit, že pokud funkce main() programu spustí libovolný počet gorutin, ale nijak nepočká na jejich provedení (tj. kdybychom třeba zakomentovali ř.23), tak celý program skončí svoje provádění dříve než budou mít další/jiné gorutiny příležitost dokončit svoji práci nebo ji dokonce vůbec zahájit. Možná se to bude někomu zdát jako zbytečná poznámka, ale v diskuzích na golang-nuts je tato chyba v dotazech začínajících programátorů v Go vidět dost často. Podobně chybné, jen opačně, je na konci main kvůli tomu např. psát nějaké zpoždění odhadovaného počtu sekund (třeba pomocí time.Sleep). Pokud je pro správnou činnost programu třeba nechat tu či onu gorutinu dokončit práci, je nutné se k takové události synchronizovat. Čekáním na příchod signálu/hlášení/výsledku kanálem je automaticky takovou synchronizací.

    V dané ukázce by bylo možné čekat na známý počet hlášení (tj. 2) třeba v dalším cyklu. Na ř.23 využíváme pro automatické spárování potřebného počtu synchronizací příkaz defer. Jeho sémantika je jednoduchá – defer příkaz, kterým musí být volání funkce – způsobí zřetězení volání takové funkce těsně před návratem z funkce, ve které provádíme příkaz defer. Defer je možné vyvolávat opakovaně, odložené volání se koná v LIFO pořadí. Teprve až poté, co je celý tento „lokální zásobník“ vyprázdněn, dojde k návratu z funkce. V našem případě z funkce main, dojde proto k ukončení celého programu, leč řádně, až po ukončení práce obou (instancí) gorutiny f.

    Právě popsaný mechanismus defer, zvláště pak skutečnost, že odložené příkazy se provedou ještě před návratem z dané funkce, se využívají pro ošetřování výjimek. Na ř.7 vidíme volání zabudované funkce recover, v rámci odloženého volání funkčního literálu na ř.6. Recover() vrací za běžných okolností nil. Pokud bylo normální provádění funkce ukončeno výjimkou, pak recover, použitý v odloženě vyvolané funkci, vrací aktuální chybový objekt. Protože recover voláme odloženě (ř.6), tak v případě výjimky, během provádění ř.8, „vidíme“ v uzávěře odložené funkce ještě platné parametry funkce f. Proto můžeme bez obav na ř.8 poslat kanálem c chybové hlášení. Kanál typu string je zde použit jenom pro zjednodušení příkladu, v main() se o obsah hlášení nijak nezajímáme, jen je vypíšeme.

    Na ř.12 uměle vytváříme chybu, představte si pod tím obecný případ neplatného argumentu/stavu/jiné chyby. Bylo by zde možné opět přímo poslat něco do kanálu c a provést return. Pokud už ale máme ošetřeno pomocí defer zachytávání výjimek, je pohodlnější toto zachycení vyvolat jednoduše pomocí panic. Navíc takto zachytíme i neošetřenou výjimku z libovolné nižší úrovně provádění (vizte příklad 2). Argumentem panic je chybový objekt. Tato zabudovaná funkce je generická, tj. chybový objekt může být jakéhokoli typu. Pro změnu chování funkce dle typu chybového objektu vizte následující příklad.

    Příklad 2.

    link
    package main 
    
    import ( 
        "fmt"
        "os"
    ) 
    
    func div(a, b int) int { 
        if b == -2 || b&0xff == 0xaa { 
            panic(fmt.Errorf("nepovolený argument %d", b)) 
        } 
    
        return a / b 
    } 
    
    var p *int 
    
    func f(x int) (y *int, err os.Error) { 
        y = new(int) 
    
        defer func() { 
            if e := recover(); e != nil { 
                y = nil 
                err = e.(os.Error) 
            } 
        }() 
    
        switch x { 
        case -1: 
            *y = *p 
        case 2: 
            panic("TODO:f(2)") 
        default: 
            *y = div(0x12345678, x) 
        } 
        return 
    } 
    
    func main() { 
        for i := -3; i <= 3; i++ { 
            v, err := f(i) 
            if err != nil { 
                fmt.Printf("f(%d) – %s\n", i, err) 
                continue 
            } 
    
            fmt.Printf("f(%d) == %d\n", i, *v) 
        } 
    }
    

    Upravit / Spustit

    Výstup:

    f(-3) == -101806632
    f(-2) – nepovolený argument -2
    f(-1) – runtime error: invalid memory address or nil pointer dereference
    f(0) – runtime error: integer divide by zero
    f(1) == 305419896
    panic: TODO:f(2) [recovered]
        panic: interface conversion: string is not os.Error: missing method String
    
    runtime.panic+0xac /tmp/sandbox/go/src/pkg/runtime/proc.c:1060
        runtime.panic(0x45a1f0, 0xf84001fd90)
    itab+0x101 /tmp/sandbox/go/src/pkg/runtime/iface.c:134
        itab(0x4547b0, 0x43ec38, 0x0, 0xf84003e048, 0x1, …)
    runtime.ifaceE2I+0xe3 /tmp/sandbox/go/src/pkg/runtime/iface.c:473
        runtime.ifaceE2I(0x4547b0, 0x43ec38, 0xf840001320, 0x2b42b055cdf8, 0xf84000b780, …)
    runtime.assertE2I+0x43 /tmp/sandbox/go/src/pkg/runtime/iface.c:488
        runtime.assertE2I(0x4547b0, 0x43ec38, 0xf840001320, 0xf84000b7b0, 0xf840001320, …)
    main._func_001+0x75 /tmpfs/gosandbox-5522aa24_eb79397b_f981defe_0fef1eaf_56f2c89a/prog.go:24
        main._func_001(0xf8400000b0, 0xf840001330, 0x401f4f, 0x2b42b055c100, 0x2b42b055cfb8, …)
    ----- stack segment boundary -----
    runtime.panic+0xf6 /tmp/sandbox/go/src/pkg/runtime/proc.c:1041
        runtime.panic(0x43ec38, 0xf840001320)
    main.f+0x114 /tmpfs/gosandbox-5522aa24_eb79397b_f981defe_0fef1eaf_56f2c89a/prog.go:32
        main.f(0x2, 0x642528660000000c, 0xf84000c740, 0x200000002, 0x12, …)
    main.main+0x39 /tmpfs/gosandbox-5522aa24_eb79397b_f981defe_0fef1eaf_56f2c89a/prog.go:41
        main.main()
    runtime.mainstart+0xf /tmp/sandbox/go/src/pkg/runtime/amd64/asm.s:77
        runtime.mainstart()
    runtime.goexit /tmp/sandbox/go/src/pkg/runtime/proc.c:178
        runtime.goexit()
    ----- goroutine created by -----
    _rt0_amd64+0x8e /tmp/sandbox/go/src/pkg/runtime/amd64/asm.s:64
    

    Tato ukázka rozvíjí příklad 1 v oblasti výjimek. Na ř.10 vyvoláváme výjimku ve funkci div, zachytává se ale o úroveň výše, na ř.22 ve funkci f. Na ř.13 budeme občas dělit nulou bez kontroly, odchycení je ale stejné. Funkce f (ř.18) je modelová funkce vracející ukazatel a příznak chyby. Na ř.19 je častý případ, kdy na počátku provádění funkce vytváříme nový objekt (alokace). V případě zachycení výjimky chceme místo ukazatele na objekt zajistit (bezpečnější) vrácení hodnoty nil, to zajišťuje ř.23. Na ř.30 občas způsobíme další typ výjimky – dereferenci nil ukazatele. Na ř.32 opět občas „zpanikaříme“, tentokrát úmyslně s chybovým objektem odlišného typu, v tomto případě string. Na ř.24 totiž provádíme run time typovou kontrolu (type assertion) chybového objektu e. Pro typ string tato kontrola selže, způsobí opět další výjimku, která už ukončí běh celého programu. To je modelové schéma, kdy potřebujeme rozlišit výjimky, které vracíme volajícímu jako chybu (s nadějí na zotavení programu) a situace, kdy pokračovat nelze – zde modelově vstupujeme do části kódu, který je teprve třeba napsat. Proto nám ve výstupu neprojdou všechny hodnoty cyklu z ř.40 a pro i == 2 program skončí neošetřenou chybou a tedy výpisem zásobníku.

    Vracení chyby typu os.Error je záležitost víceméně (ustáleného) zvyku. Na druhé straně os.Error není statický typ, je to rozhraní, takže v případě potřeby jemnějšího rozlišení kategorií chyb nebo když je nutné různé chyby doplnit o přidané informace – nám nic nebrání použít uživatelsky definovaný typ. Stačí bude‑li implementovat jedinou metodu rozhraní os.Error – String(), tj. převod na řetězec.

    Všechny typy jsou si rovné, ale některé jsou si rovnější

    link

    Příklad 3.

    link
    package main 
    
    type bad interface{} 
    
    func (b bad) foo() { 
        println("Hi from bad") 
    } 
    
    type ok interface { 
        foo() 
    } 
    
    type bar struct{} 
    
    func (b bar) foo() { 
        println("Hi from bar") 
    } 
    
    func main() { 
        var iface bad 
        iface.foo() 
        bar{}.foo() 
    } 
    

    Upravit / Spustit

    Výstup:

    prog.go:5: invalid receiver type bad
    prog.go:21: iface.foo undefined (type bad has no field or method foo)

    Všechny pojmenované typy v Go mohou mít k sobě přidružené metody. Jednou z „optických“ ne ortogonalit tohoto pravidla je to, že typ rozhraní může metody pouze deklarovat avšak nikoli implementovat. Pro všechny ostatní typy je tomu právě naopak. Příklad 3 na ř.5 implementuje metodu rozhraní bad (ř.3) a to nám kompilátor nedovolí. Jako cvičení si lze vyzkoušet uvést tento příklad do přeložitelného stavu.

    Ještě jedna (po)drobnost omezuje typy, ke kterým je možné definovat metody. Typ (přijímače metody) může být sám o sobě ukazatelem (ukazatelovým typem), ale jím odkazovaný typ už ukazatelem být nesmí. Vizte též specifikaci.

    Třikrát totéž není totéž

    link

    Říká se, vcelku oprávněně, že je dobré, když jedna sémantická konstrukce je v programovacím jazyce vyjádřitelná jenom jedním způsobem. Podíváme se nyní na tři verze skoro stejného schématu. Úmyslně je v Go napíšeme různými způsoby. Myslím ale, že v žádném příkrém rozporu s první větou tohoto odstavce nebudeme. Různé implementace v tomto případě přinášejí ne zcela shodnou sémantiku – byť rozdíly jsou, dle úhlu pohledu, spíše jen v menších detailech. Každá implementace se ale hodí pro trochu jinou situaci. Představme si třeba rozdíl mezi situací kdy jsme odkázáni na použití existující funkce/metody třetích stran vs. stav, kdy si „operátor“ můžeme/chceme a/nebo musíme napsat sami.

    Modelové schéma v našem případě je nějaká abstraktní operace nad adresářovým stromem souborového systému, přesněji řečeno provedení nějaké činnosti nad jednotlivými adresáři stromu. Kdo chce, může v tom vidět i Visitor pattern. Ve standardní knihovně existuje funkce filepath.Walk, kterou se zde inspirujeme. Pro jednoduchost degenerujeme procházení stromu na návštěvu pouze jeho kořene a modelově chceme jedním mechanismem získávat dvě různé informace – počet souborů v adresáři nebo jejich celkovou velikost. Další možnosti konkrétní „operace“ (třeba v duchu příkazů cat, echo, mv, …) si jistě lze domyslet.

    Příklad 4a.

    link
    package main 
    
    type visitor func(string) 
    
    func files(dir string) { 
        println(dir, "obsahuje celkem 42 souborů") 
    } 
    
    func bytes(dir string) { 
        println(dir, "obsahuje celkem 524287 bajtů") 
    } 
    
    func walk(path string, v visitor) { 
        v(path) 
    } 
    
    func main() { 
        walk("/", files) 
        walk("/bin", bytes) 
    } 
    

    Upravit / Spustit

    Výstup:

    / obsahuje celkem 42 souborů
    /bin obsahuje celkem 524287 bajtů

    Příklad 4a je, volně řečeno, ve stylu Cčka. Bez použití (možnosti použití) rozhraní nebo třeba virtuálních metod objektů je použití funkčního typu pro „operaci“ jednoduchým řešením – a v případě C víceméně také jediným. Pomíjíme zde nepoměrně složitější možnosti, které přináší třeba GObject, protože to už nehovoříme o jazyku, ale o jeho knihovně. Ostatně nějaký mechanismus jako vtable a vcall jde s konečným úsilím implementovat snad vždy i v ne OOP programovacím jazyku.

    Řešení (schématu) je zcela nekomplikované, jediná deklarace (funkčního typu visitor na ř.3), použitá v definici funkce walk na ř.13, je zde „nutná“ navíc jen v rámci snad dobrého stylu. Typ parametru 'v' by mohl být definován i typovým literálem – lze si ověřit na „pískovišti“ (nezkusíte si to?).

    Příklad 4b.

    link
    package main 
    
    type visitor interface { 
        visit() 
    } 
    
    type files string 
    
    func (dir files) visit() { 
        println(dir, "obsahuje celkem 42 souborů") 
    } 
    
    type bytes string 
    
    func (dir bytes) visit() { 
        println(dir, "obsahuje celkem 524287 bajtů") 
    } 
    
    func walk(path visitor) { 
        path.visit() 
    } 
    
    func main() { 
        walk(files("/")) 
        walk(bytes("/bin")) 
    } 
    

    Upravit/Spustit

    Výstup:

    / obsahuje celkem 42 souborů
    /bin obsahuje celkem 524287 bajtů

    Příklad 4b představuje obvyklý přístup, který by se asi dal nazvat Go idiomatický. Ostatně toto řešení je (schématicky) identické implementaci svého vzoru (vizte filepath.Walk a rozhraní filepath.Visitor). Na ř.3 deklarujeme rozhraní. Na ř.7 a 13 deklarujeme pojmenované typy, které toto rozhraní implementují (ř.9 a 15). Na ř.24 a 25 provádíme konverzi literálu typu string na typ files resp. bytes a tím volíme „operaci“, kterou od funkce walk požadujeme. Konverze je zde použita jen pro zkratku příkladu, jistě si snadno domyslíte obecnější případ entit různých typů.

    Příklad 4c.

    link
    package main 
    
    type visitor func(string) 
    
    func (v visitor) visit(dir string) { 
        v(dir) 
    } 
    
    func (v visitor) walk(path string) { 
        v.visit(path) 
    } 
    
    var files visitor = func(dir string) { 
        println(dir, "obsahuje celkem 42 souborů") 
    } 
    
    var bytes visitor = func(dir string) { 
        println(dir, "obsahuje celkem 524287 bajtů") 
    } 
    
    func main() { 
        files.walk("/") 
        bytes.walk("/bin") 
    } 
    

    Upravit / Spustit

    Výstup:

    / obsahuje celkem 42 souborů
    /bin obsahuje celkem 524287 bajtů

    V příkladu 3 jsme si připomenuli, že metody může implementovat každý (pojmenovaný) typ, který není rozhraní. V příkladu 4c využijeme jeden, možná trochu překvapivý, důsledek tohoto pravidla. V Go můžou mít funkce metody, korektně řečeno – metody lze implementovat i pro (pojmenovaný) funkční typ. Autor nezná dostatečně dobře dostatečný počet jiných programovacích jazyků aby mohl posloužit příkladem „stejně/podobně jako jako v jazyce X“, jen odhaduje, že něco podobného by možná šlo „spáchat“ přinejmenším v Javascriptu?

    Tato implementace nejvíce připomíná styl funkčních jazyků. Na ř.3 deklarujeme funkční typ visitor. Mimochodem deklarace je zcela stejná jako „C“ verzi v příkladu 4a. Na ř.5 a 9 definujeme metody typu visitor. Na ř.13 a 17 deklarujeme proměnné files a bytes typu visitor, v obou případech s inicializátorem pomocí funkčního literálu. Toto je implementační detail, mohli bychom definovat obyčejné funkce (s podpisem shodným s typem visitor), pak by ovšem přístup k jejich metodám byl možný pouze po konverzi ve stylu:

    func files(dir string) { 
        println(dir, "obsahuje celkem 42 souborů") 
    }
    
    //...
    
    visitor(files).walk("/") 

    Mírně složitější verze s funkčním inicializátorem, použitá v příkladu 4c, se vyplatí, pokud budeme takovou funkci, tedy přesněji metody takového funkčního typu, volat častěji, protože taková volání jsou potom krátká a dobře čitelná jak vidno na ř.22 a 23.

    Příklad 4c způsobuje v této zkratkovité podobě kontroverzní reakce – minimálně u kolegy, který Go nepoužívá, ale je ochotný tyto články před odevzdáním číst a kontrolovat. Podstatně podrobněji se tomuto „triku“ věnuje část Effective Go – Interface methods, na konci oddílu v diskuzi typu HandlerFunc a jeho metody ServeHTTP. Celý mechanismus popsaný v posledně uvedeném odkazu se reálně používá ve standardní knihovně.

    Na závěr

    link

    Pokračování by mělo vyjít snad za měsíc. Bude-li mít někdo z čtenářů zvláštní zájem o nějaké téma ke zpracování pak nechť dá prosím vědět s dostatečným předstihem.

    Laboratoře CZ.NIC

    O autorovi

    Jan Mercl, autor textu, pracuje v Laboratořích CZ.NIC jako programátor pro výzkum a vývoj.

           

    Hodnocení: 100 %

            špatnédobré        

    Nástroje: Tisk bez diskuse

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    18.5.2011 08:26 ...
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Zaujimavy pohlad: http://www.lessonsoffailure.com/software/google-go-good-for-nothing/
    18.5.2011 13:03 vlastagf | skóre: 11
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Mně se ze začátku Go vůbec nelíbilo, ale na druhou stranu jsem před pár dny nahodil kompilátor a když je čas, tak koukám na tutoriály. Co se mi moc líbí a rozčiluje mně na C++.

    a) implicitní konverze, proč tohle vůbec někoho napadlo? je to úplně proti duchu C++, kde si programátor všechno hlídá sám

    b) neuvěřitelně pomalá kompilace - píšu teď něco většího nad msvc, linkuju pár knihoven a je to děs

    c) dynamické linkování 1) možná to šetří místo v paměti, když víc aplikací používá stejnou knihovnu, ale jedna může s novější verzí přestat fungovat 2) dá se upravit aplikace jen updatem knihovny, ale stejně jednoduše se dá rebuildnout

    d) ta paralelizace vypadá dobře, člověk má uplně chuť to tak psát, v C++ jsem zkoušel TBB a Boost::Thread a nedá se to srovnat

    e) líbí se mi kopírování hodnotou, to se mi zas nikdy nelíbilo na Jávě a C#

    z) ale nelíbí se mi pevné formátování, to jsem nesnášel u Haskellu, nemám to rád u Pythonu a nebudu to mít rád ani tady. a ke všemu to asi udělali jen kvůli rychlejšímu parsování a jednodušší podpoře interpretování

    y) a kdyby se dal občas vypnout GC a člověk by po sobě uklízel sám, to bych se taky nezlobil, nemluvě o podpoře assembleru
    18.5.2011 13:54 jnml
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    y) a kdyby se dal občas vypnout GC a člověk by po sobě uklízel sám, to bych se taky nezlobil, nemluvě o podpoře assembleru
    Tělo Go funkce může být (externě) napsáno v assembleru.
    Specs: Function declarations
    Příklad: src/pkg/big
    18.5.2011 20:03 Ondřej Surý | skóre: 14
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Ad C) od toho máme v rozumných systémech SONAME a rozumní autoři knihoven jej i používají.
    Nehledejte zlý úmysl tam, kde je dostatečným vysvětlením hloupost.
    19.5.2011 18:06 Ivan
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Popripade jeste existuje verzovani symbolu vramci jedne knihovny.
    19.5.2011 21:08 Ondřej Surý | skóre: 14
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Pravda na to jsem úplně zapomněl a při tom to v Debianních balíčcích docela používám... Akorát ještě aby to taky používali autoři knihoven :(
    Nehledejte zlý úmysl tam, kde je dostatečným vysvětlením hloupost.
    vain avatar 18.5.2011 09:05 vain | skóre: 15
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Hm.. tak v tom číst tedy neumím. Když se podívám na C++, C#, Javu, Python apod... tak chápu o co jde a co znamená co, ale tohle je humáč ;-)
    If the only choice you've got is to do the wrong thing, then it's not really the wrong thing, it's more like fate.
    18.5.2011 12:07 salam
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Nesnáším otevírací závorku na konci řádku, zhoršuje to výrazně přehlednost a neplní základní funkci - otevírací a zavírací závorka jsou ve stejném sloupci (to při velkém zanoření dost pomáhá). S tímto zápisem jde o python :-)
    Solitary avatar 18.5.2011 12:41 Solitary
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Nesouhlasim, dle meho jde o dost subjektivni nazor... pokud nejsi prase a odsazujes (nemusi jit o Python, spravne odsazovat by se melo ve vsech jazycich), tak ve stejnem sloupci jako uzaviraci zavorka bude radek kde zacina dana metoda. Oteviraci zavorka na konci radku je pak nepodstatna a usetris radek v kodu. Naopak, na novem radku, ji zase nesnasim ja, dle meho to prehlednosti neprida (pribude radek) a navic to vytvari dojem, ze dana metoda k bloku nepatri.
    Bystroushaak avatar 18.5.2011 13:27 Bystroushaak | skóre: 25 | blog: Bystroushaakův blog | Praha
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Pod tohle se můžu podepsat, mám úplně stejný názor.
    vain avatar 18.5.2011 13:31 vain | skóre: 15
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Také souhlas.
    If the only choice you've got is to do the wrong thing, then it's not really the wrong thing, it's more like fate.
    18.5.2011 17:13 salam
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.

    Ano, když něco nesnáším, jde o můj subjektivní názor - to snad není třeba komentovat... :-)

    Já často spojuji velké bloky zdrojáků z různých zdrojů a časů a tam přeskok na párovou závorku a letmá kontrola čísla sloupce hodně pomáhá, používám to prakticky denně. A dále - pokud je řádek delší než zobrazený text, pak se tato závorka dostane mimo obrazovku a já pak musím při vizuální kontrole spoléhat na to, že to je dobře odsazené. Jenže pokud se ke mne dostane zdroják, kde jsou mixované tabulátory a mezery a já mám tabulátory nastavené na jinou hodnotu než autor... Prostě python :-) :-)

    To ušetření volného řádku nějak nechápu - co přesně se tím ušetří? Možná na malém monitoru, rozlišení.. No a ten dojem, že řádky následující za začátkem bloku do něj nepatří, tak to bude nejspíš ten 'dost subjektivní názor' ;-)

    Bystroushaak avatar 18.5.2011 17:28 Bystroushaak | skóre: 25 | blog: Bystroushaakův blog | Praha
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    No a ten dojem, že řádky následující za začátkem bloku do něj nepatří, tak to bude nejspíš ten 'dost subjektivní názor' ;-)
    No, to jo, ale když vidím tu závorku na novém řádku, působí to nemocně.

    Jinak ať žije autoformater :)
    18.5.2011 17:49 salam
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.

    Pro mě je nemocná ta 'schovaná' a "nepodstatná" závorka, která tak ztrácí část své funkčnosti. Ale určitě souhlasím, že čtení je věc zvyku. Problém je v tom, že ve své práci jsem ten autoformater často já sám.

    Tonocí ve zdrojáku se i závorky chytá...

    Solitary avatar 18.5.2011 18:52 Solitary
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Nekomentoval jsem tvuj nazor, ze je subjektivni (ten samozrejme je), ale to, ze nahled na danou problematiku je vzdy subjektivni a kazdy se k tomu stavi jinak. Kdyz mas kod tak dlouhy, ze presahuje sirku obrazovky, tak by mozna bylo na miste ho rozlozit na vic radku... ono kdyz neni videt kus kodu, tak se to cte blbe tak ci onak. Hlavni duvod, proc si myslim, ze je lepsi davat zavorku hned za danou metodu je ten, ze je jasne, ze ten blok kodu k tomu patri a nejde o nejaky samostatny blok.
    if(true) do();
    {
    //blok kodu
    }
    A presne v tuhle chvili by dle meho bylo velmi snadne treba prehlidnout nenapadnou metodu do() a myslet si, ze ten blok patri k podmince (zrovna treba ten pripad, kdy by vyraz v podmince byl delsi nez je sirka monitoru). Je to extrem, ale je to vec, ktera me vadi :) navic ta rozlezlost - ten radek navic me proste irituje :) je takovy chudak opusteny a vypada to, ze se k nicemu nevaze... (v tomto pripade se opravdu nevaze, a pokud bys prehledl do() tak si toho tak lehce nevsimnes)
    18.5.2011 18:59 Roger
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Tohle resi
    if (true)
      do();
    
    prip. rovnou
    if (true)
    {
      do();
    }
    
    coz dost pomaha, pokud nechcete hledat nahodnou chybu ve ctyri rano pred odevzdanim...
    Solitary avatar 18.5.2011 19:16 Solitary
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Tak samozrejme... osobne pouzivam novy radek a i zavorky u techto jednoduchych vyrazu (az na vyjimky, kdy jsem rozmarny :-) ale nikdy na ukor prehlednosti), byl to jen pripad, ktery by mohl nastat a pri tomto zapisu byt problematicky. Ono totiz ne vzdy musime cist kod, ktery jsme sami napsali, a pokud nekdo pise takto a udela neco podobneho, tak muze byt problem na svete. V pripade zapisu s oteviraci zavorkou na konci vyrazu to prakticky nehrozi.
    18.5.2011 21:25 Roger
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Jo, s tim blokem u ifu to byla vlastni (horka) zkusenost - kolega napsal
    if (neco) { blok; } else prikaz;
    a pak chtel pred prikaz doplnit ladici vypis, ale zapomnel puvodni prikaz u else dat do bloku, takze vypadl mimo if/else :( Od te doby jsem opatrny, a - kdyz nejsem rozmarny :) - radeji zavorkuju kde co.

    Taky, pokud treba odnekud kopiruju jen kus kodu a neupravuju cizi projekt, pouzivam formatovani v editoru - pak mam jakz-takz jistotu, ze se v tom da vyznat.

    Na druhou stranu - treba v jave pisu zavorky na konec, tam je to standard (a NB to tak automaticky formatuji :) ). Naopak MSVS formatuje tak, jak popisuju nahore.

    Zatim jsem se z toho jeste nezblaznil. Aspon myslim :)
    vlk avatar 18.5.2011 19:17 vlk | skóre: 21 | blog: u_vlka
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.

    takze v praci asi budes plateny od poctu riadkov, ze?

    You don't exist, Go away !
    18.5.2011 23:40 __dark__
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Každý normální programátor by před tu složenou dal mezeru. Ten váš výpis mi připadá spíš jako nějaký výstup z autoformateru, který nepřemýšlí (mimochodem normální programátor snad autoformát ani nepotřebuje). Já osobně mám rád složené závorky na samostatný řádek - nikdy mi nepřekážel větší kód, který je čitelný.
    19.5.2011 10:52 salam
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.

    Pokud někdo formátuje zdroják takto, pak je jen na místě, aby si problémy s tím spojené pěkně odladil. Nepamatuji si ale, že bych při práci někdy viděl něco podobného v takové pozici, že by to znamenalo programátorovu chybu. Samozřejmě, že tam pro lepší čitelnost patří odřádkování a klidně bych uvítal komentář, proč je tam ten extra blok.

    Já, když už při své práci více zasahuju do cizího kódu (oprava chyby), tak ho většinou poměrně dost lokálně asimiluju a tuhle (pozor nasleduje subjektivní názor ;-)) chybu formátování okamžitě opravuju, stejně jako závorky na konci řádků, velmi dlouhé řádky (to si okamžitě zvětším okno, případně zmenším písmo), chybějící odřádkování, někdy dokonce absence formátování...

    Dělám v týmu, ve kterém převážně vždy dodržujeme několik jednoduchých pravidel. Jedno z nich je primitivní: za if, for, while... se nemá schovávat NIC.

    Mini anketa: já mám běžně nastavenou velikost okna tak, že vidím ze zdrojáku 50 řádků po 150 znacích. Kolik máte vy?

    18.5.2011 20:02 Ondřej Surý | skóre: 14
    Rozbalit Rozbalit vše Re: Google Go v příkladech 1.
    Koukám, že se svět stále nezbořil a komentáře pod článkem o Go stále ve většině případů nejsou ani trochu blízko obsahu článku.

    Ale je pravda, že zatím mi tady chybí 'D'.
    Nehledejte zlý úmysl tam, kde je dostatečným vysvětlením hloupost.

    Založit nové vláknoNahoru

    ISSN 1214-1267   Powered by Hosting 90 Server hosting
    © 1999-2013 Argonit s. r. o. Všechna práva vyhrazena.