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

DESAMIS Go Training Season 1 Day 6

DESAMIS Go Training Season 1 Day 6

デザミス社内 Go 研修 (第1期) の6日目の資料です。
今回は Go の Modules 機能といくつかの外部ライブラリを紹介したのち、実際に複数の外部ライブラリを組み合わせて実用的なアプリケーションを作るハンズオンを行います。

Yutaka Kato

May 25, 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. ֎෦ϥΠϒϥϦͷར༻  package mai n import ( "context " "fmt

    " "time " "github.com/mikan/syukujitsu-go " ) func main() { entries, err := syukujitsu.FetchAndParse(context.Background() ) if err != nil { panic(err ) } fmt.Printf("%d ݅ͷॕ೔ΛಡΈࠐΈ·ͨ͠\n", len(entries) ) if name, found := syukujitsu.Find(entries, time.Now()); found { fmt.Printf("ࠓ೔͸%sͰ͢ʂ\n", name ) } else { fmt.Printf("ࠓ೔͸ॕ೔Ͱ͸͋Γ·ͤΜ\n" ) } } 👇ࣸܦͯ͠ΈΑ͏ EBZTZVLVKJUTVNBJOHP ౷߹λʔϛφϧΛ։͍ͯʮgo mod tidyʯΛ࣮ߦ͢Δͱʜ
  3. HPNPEͱHPTVN  module github.com/u-motion/go-training-1/mika n go 1.1 6 require github.com/mikan/syukujitsu-go

    v0.0.2 HPNPEʹSFRVJSF͕௥Ճ͞Εͨ github.com/mikan/syukujitsu-go v0.0.2 h1:nabT8z0OroVS8Yc2RoACF+a1UlUeGv … github.com/mikan/syukujitsu-go v0.0.2/go.mod h1:xDHnZ4BxbJlL0XQOvp7AaHO … golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M = golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDc … golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudc… HPTVN͕৽ͨʹੜ੒͞Εͨ HPTVN͸׬શͳґଘؔ܎ͷ೺Ѳͱվ͟Μ๷ࢭʹ໾ཱͭ 
 HPTVN΋(JUʹίϛοτ͢ΔϓϩδΣΫτ͕ଟ͍ 👈௚઀ͷґଘؔ܎ 👆ґଘͷґଘ
  4. όʔδϣϯఆٛ  (P.PEVMFTͰ͸4FNBOUJD7FSTJPOJOH TFNWFS ʹै͏ W TFNBOUJDWFSTJPOJOH ϝδϟʔόʔδϣϯޙํඇޓ׵ͳมߋ࣌ʹ૿Ճ ϚΠφʔόʔδϣϯ৽ػೳͷ௥Ճ࣌ʹ૿Ճ ύονόʔδϣϯόάͷमਖ਼࣌ʹ૿Ճ

    import “my/thing/v2/sub/pkg“ TFNBOUJDJNQPSUWFSTJPOJOH ϝδϟʔόʔδϣϯΛ্͛Δ ޙํඇޓ׵ͳมߋ͕͋Δ ࡍ͸ 
 ύοέʔδͷΠϯϙʔτύεΛม͑Δ
  5. (0.0%6-&؀ڥม਺ w (P.PEVMFTͷ༗ޮɾແޮΛ੾Γସ͑Δม਺ w (P͔Βಋೖ͞ΕͨͷͰ͜ͷΑ͏ͳ໊લʹͳ͍ͬͯΔ w (P͔Β͸ڧ੍PO ࢦఆͯ͠΋ແࢹ ͱͳΔ༧ఆ 

    ઃఆ આ໌ σϑΥϧτͷಈ࡞ PO HPNPE HPTVNͰґଘؔ܎ղܾ (PҎ߱ P f (01"5)TSDҎԼʹґଘؔ܎ΛऔΓࠐΉ (PҎલ BVUP HPNPE͕͋Δ৔߹͸POͱͯ͠ৼΔ෣͏ (Pʙ
  6. ༷ʑͳ؀ڥม਺  ؀ڥม਺ σϑΥϧτ஋ Α͋͘Δ࢖͍ॴ (01"5) )0.&HP64&3130'*-&HP ޷ΈͷσΟϨΫτϦͰ։ൃ͍ͨ͠ͱ͖ (03005 (PπʔϧνΣΠϯͷ৔ॴ

    ෳ਺ͷ(PόʔδϣϯΛ࢖͍෼͚Δͱ͖ (0#*/ (01"5)CJO ࣮ߦϑΝΠϧͷੜ੒৔ॴΛม͑Δͱ͖˞ (0"3$) ݱࡏͷ$16 BNE BSN౳ ΫϩείϯύΠϧ͢Δͱ͖ (004 ݱࡏͷ04 EBSXJOXJOEPXT౳ ΫϩείϯύΠϧ͢Δͱ͖ (01309: IUUQTQSPYZHPMBOHPSH EJSFDU ඇެ։ͳϞδϡʔϧΛऔಘ͍ͨ͠ͱ͖ (013*7"5& ۭ ඇެ։ͳϞδϡʔϧΛऔಘ͍ͨ͠ͱ͖ શͯͷҰཡ͸HPFOWίϚϯυͰ֬ೝͰ͖Δ ˞HPHFU΍HPJOTUBMM 
 ͢Δͱ͖ͷ࿩
  7. ެࣜϥΠϒϥϦ w ඪ४ϥΠϒϥϦʹؚΊΔ΄ͲͰ͸ͳ͍͕༗༻ͳ֎෦ϥΠϒϥϦ͕ ଟ਺ఏڙ͞Ε͍ͯΔ ४ඪ४ϥΠϒϥϦͱ΋͍ΘΕΔ  w ޓ׵ੑͷཁ͕݅ඪ४ϥΠϒϥϦΑΓ௿͍͕ɺެࣜͷ(PϓϩδΣ ΫτͷҰ෦ͱͯ͠։ൃ͞Ε͍ͯΔ w

    044ϥΠηϯε΋(Pຊମͱಉ͡#4%ϥΠηϯε ৚߲  w Πϯϙʔτύε͸ʮHPMBOHPSHYʯͰ࢝·Δ w ݟ͚ͭํ 
 IUUQTQLHHPEFWTFBSDI RHPMBOHPSH'Y 
  8. ஫໨ͷެࣜϥΠϒϥϦ  ϥΠϒϥϦ ֓ཁ HPMBOHPSHYUFYU ଟݴޠରԠͳͲ༷ʑͳ؀ڥ޲͚ͷςΩετॲཧ HPMBOHPSHYOFU *$.1͔Β8FC4PDLFU·Ͱ༷ʑͳ௨৴ϓϩτίϧͷ࣮૷ HPMBOHPSHYPBVUI 0"VUIΫϥΠΞϯτͷ࣮૷ʹศར

    HPMBOHPSHYDSZQUP ༷ʑͳ҉߸ΞϧΰϦζϜ΍44)ϓϩτίϧ౳ͷ࣮૷ HPMBOHPSHYUPPMT lHPJNQPSUTz౳ͷ͍͔ͭ͘ͷศརίϚϯυ HPMBOHPSHYNPCJMF "OESPJEJ04αϙʔτͷͨΊͷ࣮ݧతͳϓϩδΣΫτ
  9. Ϋϥ΢υϕϯμʔܥ w ༷ʑͳϕϯμʔ͕ެࣜͷ(P4%,Λఏڙ͍ͯ͠Δ w ͲΕ΋Α͘ϝϯςφϯε͞Ε͍ͯΔͷͰɺ҆৺ͯ͠࢖͑Δ  ϕϯμʔ Ϟδϡʔϧ ϥΠηϯε උߟ

    (PPHMF DMPVEHPPHMFDPNHP "QBDIF αʔϏεຖʹϞδϡʔϧ͕෼͔ΕΔ (PPHMF HPPHMFHPMBOHPSHBQJ #4%$MBVTF "1*ΫϥΠΞϯτϥΠϒϥϦू "84 HJUIVCDPNBXTBXTTELHP "QBDIF ϞδϡʔϧͰશαʔϏεΛΧόʔ "84 HJUIVCDPNBXTBXTTELHPW "QBDIF αʔϏεຖʹϞδϡʔϧ͕෼͔ΕΔ .JDSPTPGU HJUIVCDPN"[VSFB[VSFTELHP .*5 ͍͔ͭ͘ͷαʔϏε͸ผϞδϡʔϧ 0SBDMF HJUIVCDPNPSBDMFPDJHPTEL 61- 4FNBOUJD*NQPSU7FSTJPOJOH࠾༻
  10. 4BB4ܥ w ެࣜͷ΋ͷ͸ҙ֎ͱͳ͔ͬͨΓ׬੒౓͕௿͔ͬͨΓ͢Δ w ͜͜ʹڍ͛ͨ৘ใ͸কདྷ௠෗Խ͢ΔՄೳੑ͕͋Δ  αʔϏε Ϟδϡʔϧ ϥΠηϯε උߟ

    (JU)VC HJUIVCDPNHPPHMFHPHJUIVCW #4%$MBVTF ͳ͔ͥ(PPHMF͕࡞͍ͬͯΔ 4MBDL HJUIVCDPNTMBDLHPTMBDL #4%$MBVTF ඇެ͕ࣜͩ׆ൃʹ։ൃ 5XJUUFS HJUIVCDPNEHIVCCMFHPUXJUUFS .*5 ݩ5XJUUFSࣾһ͕։ൃ ,JOUPOF HJUIVCDPNLJOUPOFHPLJOUPOF #4%$MBVTF ެ͕ࣜͩόʔδϣϯ͕Wࢭ·Γ 4BMFTGPSDF   ྑ͍΋ͷ͕ͳ͍ͷͰࣗྗͰ࡞Ζ͏ʂ #PY   ྑ͍΋ͷ͕ͳ͍ͷͰࣗྗͰ࡞Ζ͏ʂ
  11. 45&1ϦϙδτϦͷ࡞੒  IUUQTHJUIVCDPNOFX 
 ʹΞΫηε͠ɺҎԼΛೖྗ 0XOFS ࣗ෼ͷΞΧ΢ϯτ 3FQPTJUPSZ/BNF TIVLVKJUTVHP %FTDSJQUJPO

    ྫ ಺ֳ෎΢ΣϒαΠτ͔Βॕ೔$47Λऔ ಘͯ͠ϓϩάϥϜͰར༻͠΍͘͢͠·͢ 1VCMJD1SJWBUF 1VCMJD "EEB3&"%.& fi MF ☑ νΣοΫ "EEHJUJHOPSF ☑UFNQMBUF(P $IPPTFBMJDFOTF #4%$MBVTF
  12. 45&1ϦϙδτϦͷෳ੡   74$PEFΛ։͖ʮΑ͏ͦ͜ʯը໘Λදࣔͤ͞·͢ 
 ϝχϡʔͷ<ϔϧϓ><Α͏ͦ͜>Ͱݺͼग़͠Մೳ   ʮ(JUϦϙδτϦͷΫϩʔϯʜʯΛΫϦοΫ͠·͢ 

    ೖྗ૭ʹ͋Δʮ(JU)VC͔Βෳ੡ʯΛબ୒͠·͢  ʮ(JU)VCϢʔβʔTIVLVKJUTVHPʯͱλΠϓ͠ɺબ୒͠·͢  ʮϗʔϜσΟϨΫτϦTSDHJUIVCDPNʯʹʮ(JU)VCϢʔβʔʯͷϑΥϧμ Λ࡞Γ·͢  ࡞ͬͨϑΥϧμʹೖͬͯʮϦϙδτϦͷ৔ॴΛબ୒ʯϘλϯΛΫϦοΫ͠·͢  μΠΞϩά͕ग़ΔͷͰʮ৽͍͠΢Οϯυ΢Ͱ։͘ʯϘλϯΛΫϦοΫ͠·͢
  13. 45&1࣮૷ͦͷ  // Package shukujitsu ͸಺ֳ෎͕ఏڙ͍ͯ͠Δॕ೔Ұཡ CSV ϑΝΠϧΛऔಘɾղੳ͠·͢ɻ package shukujits

    u // import লུ.. . // Entry ͸ॕ೔1೔෼ͷ৘ใΛอ࣋͢Δߏ଄ମͰ͢ɻ type Entry struct { YMD strin g Name strin g } const csvURL = "https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv " // AllEntries ͸಺ֳ෎΢ΣϒαΠτ͔Βॕ೔ CSV Λऔಘͯ͠ Entry εϥΠεʹม׵͠·͢ɻ func AllEntries() ([]Entry, error) { resp, err := http.Get(csvURL ) if err != nil { return nil, fmt.Errorf("઀ଓʹࣦഊ͠·ͨ͠: %w", err ) } defer resp.Body.Close( ) body, err := io.ReadAll(resp.Body ) if err != nil { return nil, fmt.Errorf("σʔλͷऔಘʹࣦഊ͠·ͨ͠: %w", err ) } // TOD O }
  14. 45&1࣮૷ͦͷ  // Package shukujitsu ͸಺ֳ෎͕ఏڙ͍ͯ͠Δॕ೔Ұཡ CSV ϑΝΠϧΛऔಘɾղੳ͠·͢ɻ package shukujits

    u // import লུ.. . // Entry ͸ॕ೔1೔෼ͷ৘ใΛอ࣋͢Δߏ଄ମͰ͢ɻ type Entry struct { YMD strin g Name strin g } const csvURL = "https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv " // AllEntries ͸಺ֳ෎΢ΣϒαΠτ͔Βॕ೔ CSV Λऔಘͯ͠ Entry εϥΠεʹม׵͠·͢ɻ func AllEntries() ([]Entry, error) { resp, err := http.Get(csvURL ) if err != nil { return nil, fmt.Errorf("઀ଓʹࣦഊ͠·ͨ͠: %w", err ) } defer resp.Body.Close( ) body, err := io.ReadAll(resp.Body ) if err != nil { return nil, fmt.Errorf("σʔλͷऔಘʹࣦഊ͠·ͨ͠: %w", err ) } // TOD O } 👆 ͜ͷίϝϯτ͸ඞͣʮ1BDLBHFQLHʜʯ͔Βॻ͖࢝ΊΔ 👆 ͜ͷίϝϯτ͸ඞͣܕͷ໊લ͔Βॻ͖࢝ΊΔ 👆 ͜ͷίϝϯτ΋ؔ਺ͷ໊લ͔Βॻ͖࢝ΊΔ
  15. 45&1࣮૷ͦͷ   JNQPSUʹҎԼͷߦΛ௥Ճ͠·͢ "golang.org/x/text/encoding/japanese " "golang.org/x/text/transform "  ઌఔͷʮ50%0ʯΛҎԼʹஔ͖׵͑·͢

    records, err := csv.NewReader(transform.NewReader(bytes.NewReader(body), japanese.ShiftJIS.NewDecoder())).ReadAll( ) if err != nil { return nil, fmt.Errorf("σʔλͷղੳʹࣦഊ͠·ͨ͠: %w", err ) } var entries []Entr y for i, row := range records { if i == 0 { continue // ϔομʔߦΛεΩοϓ } if len(row) != 2 { return nil, fmt.Errorf("૝ఆ֎ͷσʔλʹૺ۰͠·ͨ͠: ߦ %d = %v", i+1, row ) } entries = append(entries, Entry{YMD: row[0], Name: row[1]} ) } return entries, nil
  16. 45&1֬ೝ   ౷߹λʔϛφϧͰʮHPNPEUJEZʯʻ&OUFSʼΛ࣮ߦ͠·͢  ʮDNEEFNPʯϑΥϧμΛ࡞੒͠ʮNBJOHPʯΛ࡞੒ɺҎԼΛೖྗ͠·͢  ίʔυ͸ʮHPSVODNEEFNPNBJOHPʯͰ࣮ߦͰ͖·͢ package mai

    n // import লུ.. . func main() { entries, err := shukujitsu.AllEntries( ) if err != nil { panic(err ) } for _, e := range entries { fmt.Printf("%s = %s\n", e.YMD, e.Name ) } }
  17. 45&1(JU)VC΁൓ө   74$PEFͷιʔε؅ཧλϒͰશͯͷมߋΛεςʔδ ͠ίϛοτ͠·͢ ϝοηʔδ͸ద౰   <ʜ>Ϙλϯ͔Β<λά><λάΛ࡞੒>Λબ୒͠·͢ 

    ʮWʯͱೖྗ͠ʻ&OUFSʼɺଓ͘ϝοηʔδೖྗ ͸ۭཝͷ··ʻ&OUFSʼͱ͠·͢  ը໘ࠨԼͷϒϥϯν໊ͷӈʹ͋Δมߋͷಉظද͔ࣔ Βϓογϡ͠·͢  ϝχϡʔͷ<දࣔ><ίϚϯυύϨοτ>Λ։͖ɺ ʮ(JU1VTI5BHTʯʻ&OUFSʼ 2 4
  18. ίʔυΛॻ͖ऴ͑ͨΒ w ʮϢʔβʔ໊QSBDUJDFʯϒϥϯνͰ࡞ۀ͍ͯ͠Δ͜ͱΛ֬ೝ͍ͯͩ͘͠͞ w 74$PEFͷҰ൪ࠨԼʹදࣔ͞Ε͍ͯ·͢ w มߋΛεςʔδ͠ɺίϛοτ͍ͯͩ͘͠͞ w 74$PEFͷࠨϝχϡʔͷʮιʔε؅ཧʯ͔Βૢ࡞ w

    ίʔυΛ(JU)VCʹϓογϡ͍ͯͩ͘͠͞ w 74$PEFͷҰ൪ࠨԼͷϒϥϯν໊ͷ͙͢ӈʹ͋ΔΞΠίϯ͔Βૢ࡞ ্ਤ  w ϓϧϦΫΤετΛ࡞੒͍ͯͩ͘͠͞ w ʮιʔε؅ཧʯͷ্෦ʹΞΠίϯ͕͋Γ·͢