snippets
golang

snippet: go (match, 配列、乱数、ループ、キー入力、別ファイルに分ける)

文字列

Sprintf等

  • Printlnはフォーマットを指定できない。改行がつく。
  • Printfはフォーマットを指定できる。
  • Sprintfは標準出力しない。
sprintf.go
package main

import (
        "fmt"
        "time"
)
func main() {
        now := time.Now()
        fmt.Printf("%04d-%02d-%02d",now.Year(), now.Month(), now.Day())
}

match

match.go
package main

import (
        "fmt"
        "regexp"
)

func main() {
        var message string
        message = "これは日本語です"

        // match
        re := regexp.MustCompile(`日(本)語`)
        if re.MatchString(message) {
                str := re.ReplaceAllString(message, "$1")
                fmt.Println(str) //これは本です

                str = re.FindString(message)
                fmt.Println(str) //日本語
        } else {
                fmt.Println("なし")
        }
}

ファイル操作

ファイル書き込み

write.go
package main

import (
    "io/ioutil"
    "os"
)

func main() {
    content := []byte("hello world\n")
    // 共有フォルダ に書き込む場合
    ioutil.WriteFile("\\\\192.168.100.1\\share\\b.log", content, os.ModePerm)
    // c:\temp\a.log に書き込む場合
    ioutil.WriteFile("c:\\temp\\a.log", content, os.ModePerm)
}
エラーチェック(ver1.7.4)
package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

func main() {
    fwrite("a.txt", []byte("hello world\n"))
    fwrite("/a/a.txt", []byte("hello world\n"))
}

func fwrite(filepath string, content []byte) {
    err := ioutil.WriteFile(filepath, content, os.ModePerm)
    if err != nil {
        fmt.Println("書き込み失敗: " + filepath)
    } else {
        fmt.Println("書き込み成功: " + filepath)
    }
}

ファイル権限

os.Chmod("a.txt", 0600)

ファイル読み込み

read.go
package main

import (
    "fmt"
    "io/ioutil"
    //"os"
)

func main() {
    fread("a.txt")
}

func fread(filepath string) {
    res, err := ioutil.ReadFile(filepath)
    if err != nil {
        fmt.Println(err.Error())
    } else {
        fmt.Println(string(res))
    }
}

構文

配列

配列
package main
import "fmt"

func main() {
        var motion string
        actions := []string{" ", "p", "k", "<", ">"}
        motion = actions[2]
        fmt.Println(motion) //k
}

連想配列

連想配列
actions := map[string]string{" ": " ", "p": "p", "k": "k", "<": "<", ">": ">"}

乱数

ランダム
import (
    "math/rand"
    "time"
)
...
rand.Seed(time.Now().UnixNano())
motion = actions[rand.Intn(5)]

繰り返し

繰り返し
for i:=0; i<x; i++ {
    space += " "
}

永久ループ

永久ループ
for {
}

キー入力

func keydown() string {
    var k string
    fmt.Scan(&k)
    return k
}

actions := map[string]string{" ": " ", "p": "p", "k": "k", "<": "<", ">": ">"}
var key string
key = keydown()
motion = actions[key]

別ファイルに分ける

別ファイルに分ける (別package名)

  • 1文字目が大文字だと他から呼べる
act/act.go
package act

func x_space(x int) string {
    var space string
    for i:=0; i<x; i++ {
        space += " "
    }
    return space
}

func P(x int) string {
    var figure string
    figure += x_space(x) + " x " + "\n"
    figure += x_space(x) + " xxxxx" + "\n"
    figure += x_space(x) + " x " + "\n"
    figure += x_space(x) + "x x"
    return figure
}
a.go
import (
    "./act"
)
...
motion = act.P(x)

別ファイルに分ける (同じpackage名)

todo.go
package main

import "time"

type Todo struct {
    Name      string    `json:"name"`
    Completed bool      `json:"completed"`
    Due       time.Time `json:"due"`
}

type Todos []Todo
main.go
package main

import (
    "log"
    "net/http"

    "github.com/julienschmidt/httprouter"
)

func main() {
    router := httprouter.New()
    router.GET("/", Index)
    router.GET("/todos", TodoIndex)
    router.GET("/todos/:todoId", TodoShow)

    log.Fatal(http.ListenAndServe(":8080", router))
}
handler.go
package main

import (
    "encoding/json"
    "fmt"
    "net/http"

    "github.com/julienschmidt/httprouter"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    fmt.Fprintf(w, "Welcome!")
}

func TodoIndex(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    todos := Todos{
        Todo{Name: "Write presentation"},
        Todo{Name: "Host meetup"},
    }

    // utf-8
    w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    w.WriteHeader(http.StatusOK)

    if err := json.NewEncoder(w).Encode(todos); err != nil {
        panic(err)
    }
}

func TodoShow(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    fmt.Fprintf(w, "Todo show: %s", ps.ByName("todoId"))
}
実行
go run *.go
もしくは
go build

DB

mysql-client

go get github.com/go-sql-driver/mysql

(go getしたものは $GOPATH/src/github.com/go-sql-driver/mysql/ に入っている。)

rootアカウントのパスワード設定例
GRANT SELECT ON *.* TO root@localhost IDENTIFIED BY "root";
FLUSH PRIVILEGES;
mysql
package main

import (
    "database/sql"
    //"fmt"
    //_ "github.com/yuuki/go-sql-driver-mysql"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, err := sql.Open("mysql", "root:root@/test")
    if err != nil {
        panic(err.Error())
    }
    defer db.Close()
    db.Query("select now()")
}

通信

受け側の準備

a.php
<?php
var_dump($_POST);
8000番でlisten
php -S 0.0.0.0:8000

GET

get1.go
package main

import (
    "io/ioutil"
    "net/http"
)

func main() {

    response, _ := http.Get("http://localhost:8000/a.php")
    body, _ := ioutil.ReadAll(response.Body)
    defer response.Body.Close()

    println(string(body))

}
エラー例)8000番でlistenされていない場合
$ go run get1.go
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x48 pc=0x5eb949]

goroutine 1 [running]:
main.main()
    /home/user1/get1.go:16 +0x139
exit status 2

POST1

post1.go
package main

import (
    "io/ioutil"
    "net/http"
    "net/url"
)

func main() {

    resp, _ := http.PostForm(
        "http://localhost:8000/a.php",
        url.Values{"foo": {"bar"}},
    )

    body, _ := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()

    println(string(body))
}
結果
$ go run post1.go
array(1) {
  ["foo"]=>
  string(3) "bar"
}

POST 2

post2.go
package main

import (
    "io/ioutil"
    "net/http"
    "net/url"
    "strings"
)

func main() {

    client := &http.Client{}
    data := url.Values{"foo": {"bar"}}

    resp, _ := client.Post(
        "http://localhost:8000/a.php",
        "application/x-www-form-urlencoded",
        strings.NewReader(data.Encode()),
    )
    body, _ := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()

    println(string(body))
}
結果(先ほどと同じ)
$ go run post1.go
array(1) {
  ["foo"]=>
  string(3) "bar"
}

redirect

http.Redirect(w, r, "/todos", 303)
urlも可能
http.Redirect(w, r, "https://www.yahoo.co.jp/", 303)