http
POST値の取得
func tweet(w http.ResponseWriter, r *http.Request) {
e := r.ParseForm()
text := r.Form.Get("text")
fmt.Println(text)
}
// 以下3つとも同じ
r.Form.Get("text")
r.FormValue("text")
r.PostFormValue("text")
curlでpostの例
curl -X POST -d "text=test1" http://localhost:5937/tweet
文字列
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)