Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DESAMIS Go Training Season 1 Day 1

DESAMIS Go Training Season 1 Day 1

デザミス社内 Go 研修 (第1期) の1日目の資料です。
講義形式なのは1日目のみで、2日目以降はハンズオン主体の実践的な研修となっています。

Yutaka Kato

April 06, 2021
Tweet

More Decks by Yutaka Kato

Other Decks in Technology

Transcript

  1. ݚमܭը ճ ೔࣍ ༧ఆ λΠτϧ ୈճ  Ր  (Pͷجຊ

    ୈճ  Ր  ؀ڥߏஙͱ(JU (JU)VCͷجຊ ୈճ  Ր  جຊߏจ ୈճ  Ր  ߏ଄ମɺεϥΠεɺϚοϓ ୈճ  Ր  ඪ४ϥΠϒϥϦ͸΍Ί͙Γ ୈճ  Ր  ϞδϡʔϧγεςϜͱ֎෦ϥΠϒϥϦ ୈճ  Ր  )FSPLV(Pೖ໳ ୈճ  Ր  "84-BNCEB(Pೖ໳ ୈճ  Ր  ฒߦॲཧϓϩάϥϛϯά ୈճ  Ր  ୯ମςετٕ๏ ୈճ  Ր  σʔλϕʔεΞΫηε ୈճ  Ր  'ZOFʹΑΔ(6*ΞϓϦέʔγϣϯ։ൃ ୈճ  Ր  ࣾ಺(PϓϩδΣΫτͷίʔυղઆ
  2. ࢀߟॻ w ϓϩάϥϛϯάݴޠ(P ؙળग़൛ Ξϥ ϯɾυϊόϯ ϒϥΠΞϯɾΧʔχϋϯஶࣲా ๕थ༁ Λ༻͍·͢ w

    ݚमࢀՃ࣌ʹ͸ɺ͓खݩʹ͝༻ҙ͘ ͍ͩ͞ w ݚम಺Ͱ͸ຊจʹ͸৮Εͣɺίʔυ ྫ΍࿅श໰୊Λར༻͠·͢
  3. (Pݴޠͱ͸ (P͸Φʔϓϯιʔεͷϓϩάϥϛϯάݴޠ 
 Ͱ͋Γɺ؆ܿͰ৴པੑ͕ߴ͘ɺޮ཰తͳ 
 ιϑτ΢ΣΞͷߏஙΛ༰қʹ͠·͢ɻ HPMBOHPSHΑΓ package main import

    "fmt" func main() { fmt.Println("Hello, world!") } $ go build hello.go $ ./hello Hello, world! $ $ go run hello.go Hello, world! $ ιʔείʔυ ίϯύΠϧ࣮ߦ ίʔυΛ࣮ߦ ✔︎ $ϥΠΫͳೃછΈ΍͍͢ߏจ ✔︎ ߦ຤ηϛίϩϯෆཁ ✔︎ Πϯσϯτ͸λϒʹ౷Ұ 
  4. (PΛઃܭͨ͠ਓ w ,FO5IPNQTPO🇺🇸 w %FOOJT3JUDIJF  ͱڞʹ 
 $ݴޠͱ6OJYΛ։ൃͨ͠ਓ w

    ਖ਼نදݱɺ65'ͳͲ΋։ൃ w νϡʔϦϯά৆ ೥  w ݱ৬(PPHMF ʙ 
  5. (Pͷىݯ w (P͕ड͚ܧ͍ͩͭͷ ྲྀΕ w $ݴޠجຊߏจͳͲ w .PEVMB0CFSPO 
 Ϟδϡʔϧɾύο

    έʔδͷ֓೦ͳͲ w $41ฒߦੑͷ֓೦  ϓϩάϥϛϯάݴޠ(P1YJW ·͕͖͑ ΑΓ
  6. ٬؍తʹݟΔͱʜ 1SPHSBNNJOH MBOHVBHF 5ZQFTZTUFN (FOFSJDT .PEVMFT ($ 4ZOUBY .FUBQSPHSBN NJOH

    &YFDVUJPO /JN 4UBUJDBOE TUSPOH :FT :FT :FT NVMUJQMF BOEPQUJPOBM 1ZUIPOMJLF :FT $PNQJMFE CJOBSZ $ 4UBUJDBOE XFBL /P /P /P $ 7FSZMJNJUFE $PNQJMFE CJOBSZ $ 4UBUJDBOE XFBL :FT /P /P $MJLF -JNJUFE $PNQJMFE CJOBSZ % 4UBUJDBOE TUSPOH :FT :FT :FT PQUJPOBM $MJLF :FT $PNQJMFE CJOBSZ (P 4UBUJDBOE TUSPOH /P :FT :FT $MJLF /P $PNQJMFE CJOBSZ 3VTU 4UBUJDBOE TUSPOH :FT :FT /P $MJLF -JNJUFE $PNQJMFE CJOBSZ +BWB 4UBUJDBOE TUSPOH :FT :FT :FT NVMUJQMF $MJLF /P &YFDVUFEWJB UIF+7. 1ZUIPO %ZOBNJDBOE TUSPOH /" :FT :FT 1ZUIPO :FT &YFDVUFEWJBUIF 1ZUIPOJOUFSQSFUFS -VB %ZOBNJDBOE XFBL /" :FT :FT .PEVMBMJLF :FTWJB .FUBMVB &YFDVUFEWJBUIF -VBJOUFSQSFUFSPS -VB+*5DPNQJMFS /JNJO"DUJPO1ΑΓ ٭஫লུ 
  7. ੩తɾڧ͍ܕ෇͚ w ੩తܕ෇͚ίϯύΠϧ࣌ʹશͯͷม਺ͷܕ͕֬ఆ͍ͯ͠Δ w ڧ͍ܕ෇͚ίϯύΠϥ͕ܕͷ҆શੑΛݫີʹݕࠪ͢Δ w ܕਪ࿦ม਺એݴ࣌ʹ͢Ͱʹܕ͕෼͔͍ͬͯΕ͹ܕ໊ΛলུՄ package main import

    "fmt" func main() { var n int var s string n = 10 s = "foo" var m = n + 1 fmt.Printf("%d %d %s\n", n, m, s) // Output: 10 11 foo } package main import "fmt" func main() { n := 10 // লུม਺એݴ s := "foo" // ʏ m := n + 1 // ʏ fmt.Printf("%d %d %s\n", n, m, s) // Output: 10 11 foo } 
  8. δΣωϦΫεʜͳ͍ w (Pʹ͸ܕ҆શͳ൚༻ԽΛࢧԉ͢Δ࢓૊Έ͕ͳ͍ w (PͰ௥Ճ͞ΕͨಉظԽ.BQ͸ɺѻ͏ܕ͸શۭͯΠϯλ ϑΣʔεܕ ԿͰ΋ೖΔܕ ɺऔΓग़࣌͠ʹܕΩϟετ͕ඞཁʜ // standard

    map var m = make(map[string]string) m["foo"] = "bar" value, _ := m["foo"] m["foo"] = value + "2" δΣωϦοΫ͸ศརͰ͸͋Γ·͕͢ɺܕγεςϜͱϥϯλΠϜʹෳࡶ͞ʹΑΔίε τΛ΋ͨΒ͠·͢ɻզʑ͸ɺ͜ͷෳࡶ͞ʹݟ߹͏͚ͩͷՁ஋Λ࣋ͭઃܭͷΞΠσΞ Λ·ͩݟ͚ͭΔ͜ͱ͕Ͱ͖͍ͯ·ͤΜ͕ɺ͜Ε͔Β΋ܧଓͯ͠ߟ͍͖͑ͯ·͢ɻ  HPMBOHPSHͷ'"2ʹΑΔͱʜ // sync map var m sync.Map m.Store("foo", "bar") value, _ := m.Load("foo") m.Store("foo", value.(string)+"2") (P 
 Ͱ࠾༻ͷݟࠐʂ
  9. Ϋϥε͕ͳ͍ type Animal struct { Name string Birth time.Time }

    func (a Animal) Age() int { // Method return int(time.Since(a.Birth).Hours() / 24 / 365) } type Cattle struct { Animal // Embed ID int64 } ͋Δͷ͸ߏ଄ମͱϝιου ϨγʔόʔΛ΋ͭؔ਺ ͚ͩ ߏ଄ମͷຒΊࠐΈͰίϯϙδγϣϯΛ࣮ݱ  ஫Ӟ೥Λແࢹ
  10. ΠϯλϑΣʔε͸͋Δ type Caller interface { Call() string } type Cattle

    struct { ID string } func (c Cattle) Call() string { return "moo" } func main() { var caller Caller caller = Cattle{ID: "123"} fmt.Println(caller.Call()) // moo } ΠϯλϑΣʔεͰఆٛͨ͠ϝιουͱಉ͡γάχνϟͷϝιο υ͕ἧ͍ͬͯΕ͹୅ೖͰ͖Δ limplementsͱ͔͍Βͳ͍  👍
  11. Τϥʔॲཧ w ؔ਺͸ଟ஋ΛฦͤΔͷͰɺ໭Γ஋ʹerrorܕΛఴ͑ɺ࢖͍ख͸nil͔Λ൑ఆ͢Δ w ਖ਼௚͠ΜͲ͍͕ɺݩདྷΤϥʔϋϯυϦϯά͸ϓϩάϥϚͷ੹೚ɺؤڧʹ࡞Δบ͕ͭ͘ w ॲཧΛଧͪ੾Δpanic()ͱ͍͏ػߏ΋͋Δ͕ɺจࣈ௨Γக໋తͳ৔߹ʹͷΈ࢖͏  func fetch(url

    string) ([]byte, error) { resp, err := http.Get(url) if err != nil { return nil, fmt.Errorf("failed to communicate: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("failed to get: HTTP %s", resp.Status) } body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("failed to read: %v", err) } return body, nil } ߦதߦ͕Τϥʔॲཧʂ
  12. ςετ func Sum(list []int) int { sum := 0 for

    _, i := range list { sum += i } return sum } type sumTest struct { in []int out int } var sumTests = []sumTest{ {[]int{1, 2, 3}, 6}, {[]int{}, 0}, {[]int{-1, 1}, 1}, // Θ͟ͱ FAIL } func TestSum(t *testing.T) { for i, test := range sumTests { out := Sum(test.in) if out != test.out { t.Errorf("#%d Sum(%v) = %d, want %d", i, test.in, out, test.out) } } }  w ςετίʔυͷϑΝΠϧ໊͸ 
 
 xxx_test.go YYY͸೚ҙ  w ςετؔ਺໊͸TestͰ࢝·Γ 
 
 Ҿ਺ʹ͸*testing.TΛड͚ Δ w ཧ૝͸package΋ݩίʔυͱ 
 
 ෼཭͢Δ _testΛ͚ͭΔ
  13. ςετ $ go test -v -cover sum* === RUN TestSum

    --- FAIL: TestSum (0.00s) sum_test.go:20: #2 Sum([-1 1]) = 0, want 1 FAIL coverage: 100.0% of statements FAIL command-line-arguments 0.012s w ༷ʑͳςετ͕࣮ߦՄೳ w DPWFSͰΧόϨοδܭଌ ্ه  w SBDFͰϨʔείϯσΟγϣϯݕ஌༗ޮԽ w CFODIͱUFTUJOH#ͰϕϯνϚʔΫ࣮ߦ w ظ଴݁ՌΛίϝϯτͰॻ͍ͯςετ͢Δ͜ͱ΋Ͱ͖Δ &YBNQMFTػೳ 
  14. ͦͷଞ͋Δ΋ͷͳ͍΋ͷ w ࡾ߲ԋࢉࢠ͸ͳ͍if-elseͪΌΜͱॻ͘ w while/doจ͸ͳ͍ϧʔϓ͸forͷΈ ແݶϧʔϓ͸for {}  w map/filter/reduce/…͸ͳ͍δΣωϦΫεͳ͠Ͱ͸ʜ

    w ϥϜμࣜ͸ͳ͍ؔ਺ϦςϥϧͰಗ໊ؔ਺͸࡞ΕΔ w assert %C$ ͸ͳ͍खൈ͖Τϥʔॲཧ͢Δਓ͕ଟ͍͔Β w assertXX()౳ͷςετϔϧύʔ͸ͳ͍ૉ௚ʹجຊߏจͰ w ϙΠϯλ͸͋Δͨͩ͠ϙΠϯλԋࢉ͸ͤ͞ͳ͍Αʂ 
  15. ฒߦॲཧ w (PͰฒߦॲཧΛ ߦ͏ʹ͸ʜ func f1() { fmt.Println("f1") } func

    f2() { fmt.Println("f2") } func main() { go f1() go f2() time.Sleep(100 * time.Microsecond) } +VTUlgoz $ go run main.go f1 f2 $ go run main.go f2 f1 
  16. ฒߦॲཧ w νϟωϧΛ࢖͏ͱɺฒߦ ॲཧؒͰ஋΍ϝοηʔδ Λ΍ΓͱΓͰ͖Δ w ૹ৴จch <- x w

    ड৴จx = <-ch w ଴͚ͭͩͳΒ<-ch func f1(done chan bool) { fmt.Println("f1") done <- true } func f2(done chan bool) { fmt.Println("f2") done <- true } func main() { done1 := make(chan bool) done2 := make(chan bool) go f1(done1) go f2(done2) <-done1 <-done2 } 
  17. ฒߦॲཧ w ଟॏԽෳ਺ͷ νϟωϧΛ଴ͪड ͚ɺ 
 ࠷ॳʹड৴ͨ͠΋ ͷΛर͏ func f1(done

    chan bool) { fmt.Println("f1") done <- true } func f2(done chan bool) { fmt.Println("f2") done <- true } func main() { done1 := make(chan bool) done2 := make(chan bool) go f1(done1) go f2(done2) select { case <-done1: fmt.Println("f1 is first!") case <-done2: fmt.Println(“f2 is first!") } } $ go run main.go f1 f1 is first! f2 
 $ go run main.go f2 f2 is first! 
  18. ฒߦॲཧ w νϟωϧʹ͸஋ΛૹΓଓ͚Δ͜ͱ͕Ͱ͖Δ w ૊ΈࠐΈؔ਺close()ͰνϟωϧͷऴྃΛ଴ͪखʹ఻͑ΒΕΔ func async(counter chan int) {

    for i := 1; i <= 3; i++ { counter <- i time.Sleep(100 * time.Microsecond) } close(counter) } func main() { counter := make(chan int) go async(counter) for count := range counter { fmt.Println(count) } } $ go run main.go 1 2 3 $ 
  19. ฒߦॲཧ w όοϑΝαΠζΛࢦఆ͢ΔͱόοϑΝ͋ΓνϟωϧʹͳΔ w ड৴ʹରͯ͠ૹ৴͕ͷ৔߹͕Ӭԕʹૹ৴଴ͪʹͳΔͷΛ๷͛Δ func f1(done chan bool) {

    fmt.Println("f1") done <- true } func f2(done chan bool) { fmt.Println("f2") done <- true } func main() { done := make(chan bool, 2) go f1(done) go f2(done) <-done } $ go run main.go f2 $ go run main.go f2 f1 
  20. ฒߦॲཧͷཪଆ 1SPDFTT 1SPDFTT 1SPDFTT 5ISFBE 5ISFBE 5ISFBE $16 $16 ࣮ߦ

    ࣮ߦ εέδϡʔϦϯά 
 ίϯςΩετεΠον 
  21. ฒߦॲཧͷཪଆ 1SPDFTT 5ISFBE 5ISFBE $16 $16 ࣮ߦ NBJO 
 HPSPVUJOF

    HPSPVUJOF HPSPVUJOF ʜ ࣮ߦ ࣮ߦ ࣮ߦ ࣮ߦ ࣮ߦ ࣮ߦ 04εέδϡʔϥʔ HPϥϯλΠϜ 
 ./εέδϡʔϥʔ  ʜ
  22. ฒߦॲཧͷཪଆ w HPSPVUJOF͸ͱͯ΋ܰྔʂখ͞ͳؔ਺ͷ࣮ߦͰ΋͡ΌΜ͡ΌΜ্ཱͪ͛ͯ΋ ߏΘͳ͍ w ଞͷݴޠͷίϧʔνϯͱ͸ҟͳΓɺϓϩάϥϚ͕தஅ΍࠶։Λࢦࣔ͢Δ͜ͱ ͸Ͱ͖ͳ͍  ࣮ߦ୯Ґ ؅ཧ

    ࠷খελοΫ 
 αΠζ -JOVY ϓϦΤϯϓγϣϯ 1SPDFTT 04 .# ͋Γ 5ISFBE 04 .# ͋Γ HPSPVUJOF (Pϓϩηε ,# ϒϩοΫ͍ͯ͠Δ HPSPVUJOFͷΈ
  23.          

           (PMBOH +BWB 1ZUIPO           (PMBOH +BWB 1ZUIPO HPSPVUJOFͷҖྗ w େྔͷ.255௨৴Λߦ͏ϓϩάϥϜͰϦιʔεফඅΛൺֱ w ௨৴਺Λ૿΍ͯ͠΋ϝϞϦফඅͷ૿Ճ͕গͳ͘ɺͳ͓͔ͭ଎͍ʂ  ϝϞϦফඅྔ # ফඅ࣌ؒ T ݕূίʔυIUUQTHJUIVCDPNNJLBONRUUCFODINBSLT