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

Golang入門

Ab8c85abd123fc26817fad242cf4ad4c?s=47 uhzz
January 26, 2021

 Golang入門

社内勉強会で使用したGoの入門スライド

Ab8c85abd123fc26817fad242cf4ad4c?s=128

uhzz

January 26, 2021
Tweet

Transcript

  1. Golang入門 2019/11/30

  2. アジェンダ 0.自己紹介 1.こんにちは、Go(15min) • Goとは • Goのいいところ • プロジェクトでの使われ方 2.Goハンズオン(1h45min)

    • きほんの「き」 • goroutine(ゴルーチン) • アプリを作ってみよう
  3. 0.自己紹介 前職:社内ネットワークの運用 /保守 ←半年くらい - GUIツールを使った帯域の制御とか監視とか、、 - 空いた時間にVBAで自動化ツールを作ったりしてました。 今のプロジェクト:車両管理システムの開発  ←もうすぐ半年 -

    Go/Javaをメインに書いてます。 - GoとJavaはプロジェクトに入ってから始めました! 最近ハマってるもの:チョコ、チョコモナカジャンボ
  4. 1.こんにちは、Go

  5. Goとは - Googleが開発しているプログラミング言語(コンパイラ言語)です - 2009年11月10日に登場してから今月で10年目を迎えます - 設計者のケン・トンプソン、ロブ・パイクはGoだけでなくUTF-8の開発者でもあります。 ( ケン・トンプソンはそのほかにUNIXの開発、C言語の設計も) -

    Goのコンパイラ、ツールおよびソースコードはすべてフリー   かつオープンソースです。 - マスコットキャラはGopher(ホリネズミ) 引用元:Go(プログラミング言語)
  6. Goのいいところ

  7. ▪クロスコンパイル Goのソースコードをビルド(コンパイル)する開発環境のOSとは別のOS向けに 実行ファイルを生成することができます!! たとえば、Mac上で開発したGoのソースコードから、 - Windows用実行ファイル - Linux用実行ファイル を生成して配布することができます(便利)! Goのいいところ

  8. ▪並行処理 Goでは並行処理を「簡単」に書くことができます!! ※ここでの簡単とは、「並行処理に必要なあらゆる処理を Goが隠蔽して行ってくれるので、プログラマは並行処理したい処理に注力できる」の意で あり、並行処理簡単簡単 ♫ということではありません。 Goで並行処理を書くには、 - goroutine(”ゴルーチン”と読みます) -

    channel(そのまま”チャネル”です) の2つがキーワードになります! ※詳しくはハンズオンで説明します。 Goのいいところ
  9. プロジェクトでの使われ方

  10. 主に、バックエンドのAPIサーバに使用されています。 イメージ図: ドライブ動画送信 APIサーバ Webサーバ APIサーバでは、 ・動画をMP4形式に変換 ・変換したデータをストレージに保存 ・Webサーバに動画の場所を教える といった、デバイスやWebサーバのようなシ

    ステムから要求されたデータ処理を 得意としています!
  11. Goを採用しているオープンソースのプロダクト ▪Go ←バージョン1.5からセルフホスティング(Go自身)で開発されている ▪Docker ←コンテナの実行環境を提供 ▪Kubernetes ←コンテナ化したアプリのオーケストレーションシステム ▪Terraform ←インフラストラクチャ定義ツール ▪Grafana ←ログデータ可視化ツール

    ...などなど、インフラのソフトウェア多め!!
  12. Go、書きたくなったでしょ?

  13. 2.Goハンズオン

  14. -ハンズオンを進めるにあたって- 対象:    プログラミングの基本構文は一通り勉強したことのある方 (型を扱うプログラム(C/Java)を勉強した経験があれば尚とっつきやすいです!) ※今回Goで初めて型を扱うプログラムを勉強する方、または Goからプログラムを初めて勉強される方で、不明点がありましたら どしどし聞いてください!(私が分からない時は助けてください)

  15. -ハンズオンを進めるにあたって- ▪ハンズオンで取り扱うサンプルプログラムはGoをPCにインストール しなくても実行することができるようになっています。※一部を除く ▪Goは最初の環境構築をする必要なく、「Go Playground」という Web上でGoのプログラムを実験するための環境を用意しています! ※構文の勉強には環境構築いらずで手軽なのでオススメです! ▪また、これから説明する構文やパッケージの使い方に関して、 分かりにくいと感じたり、もっと詳しく知りたい!という場合は 「A

    Tour of Go」というチュートリアル形式で学べるサイトが あるのでそちらも併せてご活用ください。 ※「インストールした Goを動かしたいよ!」という方は、スライドで紹介するプログラムを $GOPATH/srcディレクトリ配下に「 main.go」というファイルを作成して保存し、 保存したディレクトリで、 $ go run main.go を実行してください。
  16. きほんの「き」 -構文編-

  17. ▪hello,world きほんの「き」 -構文編- package main import "fmt" func main() {

    fmt.Println("hello,world") } 「hello,world」と出力されたらOK! 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行)
  18. ▪var きほんの「き」 -構文編- package main import "fmt" func main() {

    var num int var message string = "hi!" Ver := 1.13 fmt.Println("num:", num) fmt.Println("message:", message) fmt.Println("Go version:", Ver) } 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) Goでは変数をvar (変数名) (型名)で初期化します。 変数の値は初期化するときに代入することもできます。 型推論で初期化することもできます。
  19. ▪if/else きほんの「き」 -構文編- package main import "fmt" func main() {

    if num := 1; num % 2 == 0 { fmt.Println("num is even") } else { fmt.Println("num is odd") } } 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) Goのif文は丸括弧()不要です。 また、if文条件式の前に、代入文を書くことができます。
  20. ▪for きほんの「き」 -構文編- package main import "fmt" func main() {

    for i:=0; i < 5; i++ { fmt.Println("num:", i) } list := []int{1,2,3,4,5} for i, v := range list { fmt.Printf("list[%d] : %d\n", i, v) } } 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) 通常のfor文 foreach的なfor文 ※Goにwhile文はありません。
  21. ▪switch/case きほんの「き」 -構文編- package main import "fmt" func main() {

    var num int switch num { case 0: fmt. Println("num is 0") default: fmt. Println("num is not 0" ) } } 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) Goのcase文はマッチするとデフォルトで breakします。 → break文は不要です!
  22. ▪type/struct きほんの「き」 -構文編- package main import "fmt" func main() {

    type MyInt int var num MyInt = 1 fmt.Println("num:", num) } 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) Goでは、type (任意の型名) (型名)とすることで任意の型名を宣 言して使用することができます!
  23. ▪type/struct きほんの「き」 -構文編- package main import "fmt" func main() {

    type Human struct { Name string Age int } user := Human{Name:"hoge", Age:20} fmt.Println("name:", user.Name) fmt.Println("age:", user.Age) } 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) Goにはオブジェクト指向言語における classがありません。。 その代わり、struct(構造体)といった形で変数をひとまとめにして使用する ことができます!(ほぼクラス) 構造体の要素をフィールドと言います。 初期化するときはHuman{“hoge”,20}とフィールド名を省 略することもできますし、後から値を変えることもできます! (変数名).(フィールド名)で取り出します
  24. ▪defer きほんの「き」 -構文編- package main import "fmt" func main() {

    defer fmt.Println("--- main function end ---" ) defer fmt.Println("file Close") defer fmt.Println("done") fmt.Println("--- main function start ---" ) fmt.Println("file Open") fmt.Println("processing..." ) } 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) defer文に渡した処理は呼び出し元の関数が終わる直前まで遅らせることができま す。(例のように関数が終了するタイミングでファイルを閉じる処理などを defer文で 宣言しておくような使い方 ) また、defer文は複数書くことができ、 後入れ先出し(LIFO)で実行されます。 (一番下のdeferから実行されます。)
  25. ▪func きほんの「き」 -構文編- package main import "fmt" func something(s string)

    (string, error) { result := "something returns " + s return result, nil } func main() { result, err := something("my heart") if err != nil { fmt.Println(err) } fmt.Println(result) } 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) Goでは、func 関数名(引数...)(戻り値..){}で関数を宣言することができます。 また特徴として、Goの関数は複数の戻り値を持つことができます!! この例では、文字列を引数にとって、1つの文字列と、1つのエラーを戻り値にしてい ます。※エラーを戻り値にしているのは後述
  26. きほんの「き」 -パッケージ編-

  27. パッケージとは? きほんの「き」 -パッケージ編- package main import "fmt" パッケージを使用することで、外部で提供されるプログラムを import文で宣言して 呼び出すことができます。

    (しれっと最初から登場している fmt.Println(パッケージ名.関数名)は、 外部のfmtパッケージからPrintln関数を呼び出していました) Goではmainパッケージがエントリポイント (プログラムが最初に実行されるパッケ ージ)になっています。 もちろん自作パッケージを作って import文で呼び出すことも可能です!
  28. ▪os きほんの「き」 -パッケージ編- package main import ( "fmt" "os" )

    func main() { file, err := os.OpenFile("arop.txt", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) if err != nil { fmt.Println(err) } defer file.Close() fmt.Fprintln(file, "第27回AROP") } 以下のプログラムをご自身の環境で実行してみましょう!※Playgroundで実行できませんのでご注意ください。 osパッケージでは、ファイルやディレクトリを操作することができます! ここではosパッケージのOpenFile関数を使用して、このプログラムのあるディレクトリと同じ 階層に”arop.txt”というファイルがあれば開きます。(無ければ新規作成) 開いたファイルはdeferを使うなどして閉じ忘れには気をつけましょう!
  29. ▪json きほんの「き」 -パッケージ編- package main import ( "encoding/json" "fmt" )

    type Message struct{ Text string } func main() { a := Message{Text: "happy golang!"} json, _ := json.Marshal(a) fmt.Println(string(json)) } 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) jsonパッケージでは、Go構造体(struct)をjsonオブジェクトへ変換する ことができます。 また、その逆(jsonオブジェクト → Go構造体)も可能です! ここでは、Message構造体をjsonオブジェクトに変換しています
  30. ▪net/http きほんの「き」 -パッケージ編- package main import ( "fmt" "net/http" )

    func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "very very happy golang") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } 以下のプログラムをご自身の環境で実行してみましょう!※Playgroundで実行できませんのでご注意ください。 net/httpパッケージはサーバ /クライアントの機能を提供します。 この例ではプログラムを実行して、「 http://localhost:8080」にアクセスすると 応答メッセージを返す簡易 APIサーバを構築しています!
  31. きほんの「き」 -エラー処理編-

  32. ▪エラー処理と言えば、 きほんの「き」 -エラー処理編- try { something() } catch(Exception e) {

    error(e) } 1.tryの中で何らかの処理をして、 2.何らかの処理が失敗すればcatchに入って エラー処理 と、このようによく見るtry-catch文ですが、 実はGoには例外処理が存在しません!!!
  33. file, err := os.OpenFile("arop.txt", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) if err != nil

    { fmt.Println(err) } ▪if err != nil きほんの「き」 -エラー処理編- Goでエラーを処理するためにはこう書きます。 os.OpenFile()を実行してファイルが開けなかった場合、 err変数に エラー内容が代入されます。 err変数にエラー内容が代入された場合、 err変数はnil(GoのNULL)以 外であるので、if err != nil { エラー処理 }の形でエラーを処理 します。(条件!=はイコールでないことを表しています。) 例外処理がなぜないのか気になる方は、以下の FAQを参考にしてください。 http://golang.jp/go_faq#exceptions 

  34. goroutine

  35. https://talks.golang.org/2012/waza.slide goroutine ▪goroutine/channelについて - goroutineは複数のCPUを使って1つの処理を同時に計算する「並列」ではなく、複数の 処理を同時にさばく「並行」処理で動いています。(下図参照) - 並行処理を実現するためにデータは、メモリを共有するのではなくgoroutine間で channelを使ってデータの受け渡しを行います。 本を取りに行く(goroutine4)

    本を燃やす(goroutine3) 本を運ぶ(goroutine2) 本を乗せる(goroutine1)
  36. package main import ( "fmt" "time") func saveFile(ch chan bool)

    { time.Sleep(3 * time.Second) ch <- true} func main() { ch := make(chan bool, 1) go saveFile(ch) for { if len(ch) > 0 { fmt.Println("file saved" ) break } time. Sleep(1 * time.Second) fmt. Println("waiting..." )}} 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) goroutineを起動するには、go (並行処理する関数名 )と書くだけです! (この例では、saveFile関数を非同期で実行させています。) channelの受信チェック channelを受信するまでmain関数内で別の処理を行うこと ができます!(複数の処理を同時に行う) channelを送信 goroutine
  37. アプリを作ってみよう

  38. つくるもの:IP管理ツール アプリを作ってみよう WEBサーバ テキストファイル (JSON形式) 概要:IPとホスト名の情報を表示 /更新/削除できるWEBアプリ 次の機能を持ったAPIを実装します。 1.表示:JSON形式のテキストファイルを読み込んだ HTMLファイルを返します。

    2.更新:POSTメソッドを使って、IP/ホスト名の情報を更新します。 3.削除:POSTメソッドを使って、IP/ホスト名の情報を削除します。 HTMLファイル
  39. アプリを作ってみよう ディレクトリ構成 golang_in_handson ├── main.go ←今回編集するファイル └── static ├── seed.json ←このファイルに管理情報をjson形式で保存 └──

    index.html ←今回編集しなくて良いファイル ドライブから課題をダウンロードしてください!
  40. 課題1: http://localhost:8080/にアクセスして、index.htmlを表示させる。 課題2: POSTメソッドを使って、次の情報をテキストファイルに追加する。 - IP: 192.168.0.10 - Host: USER10 -

    Status: available ※追加できたら、index.htmlを表示して確認しましょう。 課題3: POSTメソッドを使って、STEP2で追加した情報を テキストファイルから削除する。 ※削除できたら、index.htmlを表示して確認しましょう。 ※main.goを編集した後に 、$ go run main.goで起動してから確認してください! アプリを作ってみよう
  41. 参考 -Goのインストール- 方法1:公式の手順でインストール(英語)(https://golang.org/doc/install) 方法2: - Mac https://qiita.com/Noah0x00/items/63e024f9b5a27276401b - Linux   https://qiita.com/notchi/items/5f76b2f77cff39eca4d8

    - Windows https://qiita.com/yoskeoka/items/0dcc62a07bf5eb48dc4b
  42. お疲れ様でした