【自己学習用】はじめてのGo4
encoding/jsonパッケージ
JSONを扱うためにはencoding/jsonパッケージを用いる。
構造体にデータを代入し、ポインタをjson.Marshal()に渡すだけで,デフォルトのフォーマットでJSON文字列の[]byteを生成できる。
type Person struct {
ID int
Name string
Email string
Age int
Address string
memo string
}
func main() {
person := &Person{
ID: 1,
Name: "Gopher",
Email: "[email protected]",
Age: 5,
Address: "",
memo: "golang lover",
}
b, err := json.Marshal(person)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b)) // 文字列に変換
}
/* 出力結果
{
"ID": 1,
"Name": "Gopher",
"Email": "[email protected]",
"Age": 5,
"Address": ""
}
*/
小文字で始まるプライベートなメンバは出力結果に含まれない。
パブリックなメンバを出力しないようにしたり、結果のメンバ名を変えたい場合は構造体にタグを記述する。
プライベートなメンバを出力するようにするにはメンバ名を変更するしかない模様。
/*
`json:"name"` // nameというキーで格納する
`json:"-"` // JSONに格納しない
`json:",omitempty"` // 値が空なら無視
`json:",string"` // 値をJSONとして格納
*/
type Person struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"-"`
Age int `json:"age"`
Address string `json:"address,omitempty"`
memo string
}
JSONから構造体への変換
逆にJSONの文字列からデータをマップした構造体を生成するには,json.Unmarshal()を使用する。
func main() {
var person Person
b := []byte(`{"id":1,"name":"Gopher","age":5}`)
err := json.Unmarshal(b, &person)
if err != nil {
log.Fatal(err)
}
fmt.Println(person) // {1 Gopher 5 }
}
ファイルの書き込み
他の言語と大して変わらないので省略!
net/httpパッケージ
簡単なhttpサーバの実装。
package main
import (
"fmt"
"net/http"
)
func IndexHandler(w http.ResponseWriter,
r *http.Request) {
fmt.Fprint(w, "hello world")
}
func main() {
http.HandleFunc("/", IndexHandler)
http.ListenAndServe(":3000", nil)
}
http.HandleFunc()でルーティングの設定。
ルートパス(/)に対するリクエスト(IndexHandler)を設定。
http.ListenAndServe()でポート指定してサーバを起動。
http://localhost:3000/
をブラウザから実行すると"hello world"が表示される。
POST
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
)
type Person struct {
ID int `json:"id"`
Name string `json:"name"`
}
func IndexHandler(w http.ResponseWriter,
r *http.Request) {
fmt.Fprint(w, "hello world")
}
func PersonHandler(w http.ResponseWriter,
r *http.Request) {
defer r.Body.Close() // 処理の最後にBodyを閉じる
if r.Method == "POST" {
// リクエストボディをJSONに変換
var person Person
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&person)
if err != nil { // エラー処理
log.Fatal(err)
}
// ファイル名を {id}.txtとする
filename := fmt.Sprintf("%d.txt", person.ID)
file, err := os.Create(filename) // ファイルを生成
if err != nil {
log.Fatal(err)
}
defer file.Close()
// ファイルにNameを書き込む
_, err = file.WriteString(person.Name)
if err != nil {
log.Fatal(err)
}
// レスポンスとしてステータスコード201を送信
w.WriteHeader(http.StatusCreated)
}
}
func main() {
http.HandleFunc("/", IndexHandler)
http.HandleFunc("/persons", PersonHandler) //curl http://localhost:3000/persons -d '{"id":1,"name":"gopher"}'
http.ListenAndServe(":3000", nil)
}
html/templateパッケージ
テンプレートの作成
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
)
type Person struct {
ID int `json:"id"`
Name string `json:"name"`
}
func IndexHandler(w http.ResponseWriter,
r *http.Request) {
fmt.Fprint(w, "hello world")
}
func PersonHandler(w http.ResponseWriter,
r *http.Request) {
defer r.Body.Close() // 処理の最後にBodyを閉じる
if r.Method == "POST" {
// リクエストボディをJSONに変換
var person Person
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&person)
if err != nil { // エラー処理
log.Fatal(err)
}
// ファイル名を {id}.txtとする
filename := fmt.Sprintf("%d.txt", person.ID)
file, err := os.Create(filename) // ファイルを生成
if err != nil {
log.Fatal(err)
}
defer file.Close()
// ファイルにNameを書き込む
_, err = file.WriteString(person.Name)
if err != nil {
log.Fatal(err)
}
// レスポンスとしてステータスコード201を送信
w.WriteHeader(http.StatusCreated)
}
}
func main() {
http.HandleFunc("/", IndexHandler)
http.HandleFunc("/persons", PersonHandler) //curl http://localhost:3000/persons -d '{"id":1,"name":"gopher"}'
http.ListenAndServe(":3000", nil)
}
テンプレートの作成
テンプレートを作成し、その中にパラメータを埋め込んで使用する。
構造体の値を埋め込むなら.〇〇。
<!DOCTYPE html>
<title>person</title>
<h1>{{ .ID }} : {{ .Name }}</h1>
使用するときはコンパイルしてから。
テンプレートのコンパイルはParseFiles()を用いる。
テンプレートへの値の埋め込み
コンパイルしたテンプレートに実際に値を埋め込むには,Execute()を用いる。
第二引数に渡した構造体がテンプレートの{{ .〇〇 }}にセットされる。
package main
import (
"encoding/json"
"fmt"
"html/template"
"io/ioutil"
"log"
"net/http"
"os"
"strconv"
)
type Person struct {
ID int `json:"id"`
Name string `json:"name"`
}
func IndexHandler(w http.ResponseWriter,
r *http.Request) {
fmt.Fprint(w, "hello world")
}
// テンプレートのコンパイル
var t = template.Must(template.ParseFiles("index.html"))
func PersonHandler(w http.ResponseWriter,
r *http.Request) {
defer r.Body.Close() // 処理の最後にBodyを閉じる
if r.Method == "POST" {
// リクエストボディをJSONに変換
var person Person
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&person)
if err != nil { // エラー処理
log.Fatal(err)
}
// ファイル名を{id}.txtとする
filename := fmt.Sprintf("%d.txt", person.ID)
file, err := os.Create(filename) // ファイルを生成
if err != nil {
log.Fatal(err)
}
defer file.Close()
// ファイルにNameを書き込む
_, err = file.WriteString(person.Name)
if err != nil {
log.Fatal(err)
}
// レスポンスとしてステータスコード201を送信
w.WriteHeader(http.StatusCreated)
} else if r.Method == "GET" {
// パラメータを取得
id, err := strconv.Atoi(r.URL.Query().Get("id"))
if err != nil {
log.Fatal(err)
}
filename := fmt.Sprintf("%d.txt", id)
b, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal(err)
}
// personを生成
person := Person{
ID: id,
Name: string(b),
}
// レスポンスにエンコーディングしたHTMLを書き込む
t.Execute(w, person)
}
}
func main() {
http.HandleFunc("/", IndexHandler)
http.HandleFunc("/persons", PersonHandler)
//POST curl http://localhost:3000/persons -d '{"id":1,"name":"gopher"}'
//GET http://localhost:3000/persons?id=1
http.ListenAndServe(":3000", nil)
}
ここまででGoの言語学習は終了。
Goの印象としては
分かりにくいところはなくjava等が理解できれば問題なく理解可能
例外処理がなくてpanicになっている箇所くらい?
ラムダ式は使えない・・・?調べてもちょっとわからなかった
html/templateパッケージは実際どの程度使用されているのか疑問
vueやreactとの相性は?という点で
次回からGoのWebFrameWorkを選定していく。
その中で疑問点は明らかにしていきたい。
Author And Source
この問題について(【自己学習用】はじめてのGo4), 我々は、より多くの情報をここで見つけました https://qiita.com/y_nomura_CR/items/8d1c60bce1790d3c80b3著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .