abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 04:33 | Bezpečnostní upozornění

    Byla vydána verze 0.81 telnet a ssh klienta PuTTY. Opravena je kritická bezpečnostní chyba CVE-2024-31497 obsažena ve verzích 0.68 až 0.80. Používáte-li klíč ECDSA NIST P521 a použili jste jej v PuTTY nebo Pageantu, považujte jej za kompromitovaný.

    Ladislav Hagara | Komentářů: 0
    včera 21:44 | Komunita

    Hra MineClone2 postavena nad voxelovým herním enginem Minetest byla přejmenována na VoxeLibre.

    Ladislav Hagara | Komentářů: 0
    včera 19:11 | IT novinky

    Společnosti Avast Software s.r.o. byla pravomocně uložena pokuta ve výši 351 milionů Kč. Tu uložil Úřad pro ochranu osobních údajů za neoprávněné zpracování osobních údajů uživatelů jejího antivirového programu Avast a jeho rozšíření internetových prohlížečů (Browser Extensions), k čemuž docházelo prokazatelně po část roku 2019.

    … více »
    Ladislav Hagara | Komentářů: 1
    včera 15:55 | Zajímavý článek

    Bylo vydáno do češtiny přeložené číslo 714 týdeníku WeeklyOSM přinášející zprávy ze světa OpenStreetMap.

    Ladislav Hagara | Komentářů: 0
    včera 15:44 | Pozvánky

    V sobotu 20. dubna lze navštívit Maker Faire Jihlava, festival plný workshopů, interaktivních činností a především nadšených a zvídavých lidí.

    Ladislav Hagara | Komentářů: 0
    včera 14:44 | Zajímavý software

    Knihovna pro potlačení šumu RNNoise byla vydána ve verzi 0.2. Kvalitu potlačení lze vyzkoušet na webovém demu.

    Ladislav Hagara | Komentářů: 0
    včera 04:33 | Nová verze

    FRRouting (FRR) (Wikipedie), tj. softwarová sada pro směrování síťové komunikace, fork Quagga, byl vydán ve verzi 10.0.

    Ladislav Hagara | Komentářů: 0
    včera 03:22 | Nová verze

    Julian Andres Klode vydal APT (Advanced Packaging Tool) ve verzích 2.9.0 a 2.9.1. Jedná se o vývojové verze nové větve APT 3.0. Vylepšuje se uživatelské rozhraní. Přidány byly barvičky. Aktuální náhledy a vývoj lze sledovat na Mastodonu.

    Ladislav Hagara | Komentářů: 3
    14.4. 17:00 | Komunita

    Miguel de Icaza se na svém blogu rozepsal o vložitelných herních enginech. Kdysi slibné projekty UrhoSharp a Urho3D jsou již mrtvé. Zůstává Godot. Aktuálně vývojáři řeší Pull request #90510 s návrhem knihovny LibGodot.

    Ladislav Hagara | Komentářů: 0
    14.4. 03:44 | Nová verze

    Byla vydána nová verze 5.0 linuxové distribuce Lakka, jež umožňuje transformovat podporované počítače v herní konzole. Nejnovější Lakka přichází s RetroArchem 1.17.0.

    Ladislav Hagara | Komentářů: 0
    KDE Plasma 6
     (60%)
     (13%)
     (2%)
     (25%)
    Celkem 404 hlasů
     Komentářů: 4, poslední 6.4. 15:51
    Rozcestník

    Google Go v příkladech 1.

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

    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 Foo Bar | 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í.
    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 Foo Bar | 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 :(
    vain avatar 18.5.2011 09:05 vain | skóre: 16
    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: 36 | 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: 16
    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: 36 | 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: 23 | 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 Foo Bar | 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'.

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.