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

Golang入門

uhzz
January 26, 2021

 Golang入門

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

uhzz

January 26, 2021
Tweet

More Decks by uhzz

Other Decks in Programming

Transcript

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

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

    fmt.Println("hello,world") } 「hello,world」と出力されたらOK! 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行)
  3. ▪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 (変数名) (型名)で初期化します。 変数の値は初期化するときに代入することもできます。 型推論で初期化することもできます。
  4. ▪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文条件式の前に、代入文を書くことができます。
  5. ▪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文はありません。
  6. ▪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文は不要です!
  7. ▪type/struct きほんの「き」 -構文編- package main import "fmt" func main() {

    type MyInt int var num MyInt = 1 fmt.Println("num:", num) } 以下のプログラムをPlaygroundまたはご自身の環境で実行してみましょう!(Playgroundで実行) Goでは、type (任意の型名) (型名)とすることで任意の型名を宣 言して使用することができます!
  8. ▪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}とフィールド名を省 略することもできますし、後から値を変えることもできます! (変数名).(フィールド名)で取り出します
  9. ▪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から実行されます。)
  10. ▪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つのエラーを戻り値にしてい ます。※エラーを戻り値にしているのは後述
  11. パッケージとは? きほんの「き」 -パッケージ編- package main import "fmt" パッケージを使用することで、外部で提供されるプログラムを import文で宣言して 呼び出すことができます。

    (しれっと最初から登場している fmt.Println(パッケージ名.関数名)は、 外部のfmtパッケージからPrintln関数を呼び出していました) Goではmainパッケージがエントリポイント (プログラムが最初に実行されるパッケ ージ)になっています。 もちろん自作パッケージを作って import文で呼び出すことも可能です!
  12. ▪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を使うなどして閉じ忘れには気をつけましょう!
  13. ▪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オブジェクトに変換しています
  14. ▪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サーバを構築しています!
  15. ▪エラー処理と言えば、 きほんの「き」 -エラー処理編- try { something() } catch(Exception e) {

    error(e) } 1.tryの中で何らかの処理をして、 2.何らかの処理が失敗すればcatchに入って エラー処理 と、このようによく見るtry-catch文ですが、 実はGoには例外処理が存在しません!!!
  16. 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 

  17. 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
  18. 課題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で起動してから確認してください! アプリを作ってみよう