たなしょのメモ

日々勉強していることをつらつらと

週報8/3

Go

iota

自動で値が格納されるとは便利。
KB、MB、GBの例があったけどすごく感動した。

package main

import "fmt"

const (
    c1 = iota
    c2
    c3
)

const (
    _      = iota
    KB int = 1 << (10 * iota)
    MB
    GB
)

func main() {
    fmt.Println(c1, c2, c3)
    fmt.Println(KB, MB, GB)
}

context

チャネルのタイムアウトなどを管理することができるのか。    ある程度使い方を覚えれば便利そう。

package main

import (
    "context"
    "fmt"
    "time"
)

func longProcess(ctx context.Context, ch chan string) {
    fmt.Println("run")
    time.Sleep(2 * time.Second)
    fmt.Println("finish")
    ch <- "result"
}

func main() {
    ch := make(chan string)
    ctx := context.Background()
    ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
    defer cancel()
    go longProcess(ctx, ch)

CTXLOOP:
    for {
        select {
        case <-ctx.Done():
            fmt.Println(ctx.Err())
            break CTXLOOP
        case <-ch:
            fmt.Println("success")
            break CTXLOOP
        }
    }
    fmt.Println("################")
}

ioutil

ファイルの操作等で使うらしい。便利そう。 ```go package main

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

func main() { content, err := ioutil.ReadFile("iota.go") if err != nil { log.Fatal(err) } fmt.Println(string(content))

} ```

バイトで詰めた文字を読むこむ際にも便利そう。 ```go package main

import ( "bytes" "fmt" "io/ioutil" _ "log" )

func main() { r := bytes.NewBuffer([]byte("abc")) content, _ := ioutil.ReadAll(r) fmt.Println(string(content)) } ```

### http http通信を実施する際に使用する。
http.Getを使って取得できる。 ```go package main

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

func main() { resp, _ := http.Get("http://example.com") defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body)) }

対象のhtmlを触るのは下記のようにするといいいらしい(POSTをしている)   
イマイチ理解できない。  

package main

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

func main() { base, _ := url.Parse("https://example.com/") reference, _ := url.Parse("/test?a=1&b=2") endpoint := base.ResolveReference(reference).String() fmt.Println(endpoint)

req, _ := http.NewRequest("POST", endpoint, bytes.NewBuffer([]byte("password")))
q := req.URL.Query()
q.Add("c", "3&%")
fmt.Println(q)
fmt.Println(q.Encode())
req.URL.RawQuery = q.Encode()

var client *http.Client = &http.Client{}
resp, _ := client.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))

}

### marshal,unmarshal
jsonを特定の出力形式に変更することをUnmarshal。   
特定の出力形式をjsonに変更することをmarshal。   
出力する値のラベルを変更する場合は構造体に\`json:\`をつけて記載する。   
空の場合表示させないようにするには上記の\`json:\`にomitemptyを追加してあげれば動かなくてすむ。    
marhalを改造したい場合、MarsalJSONという関数を作って処理を記載すればいい。    

package main

import ( "encoding/json" "fmt" )

type T struct{}

type Person struct { Name string json:"name,omitempty" Age int json:"age,omitempty" Nickname []string json:"nicknames,omitempty" T *T json:"T,omitempty" }

func (p Person) MarshalJSON() (byte, error) { v, err := json.Marshal(&struct { Name string }{ Name: "Mr." + p.Name, }) return v, err }

func main() { b := byte({"name":"mike","age":20,"nicknames":{}}) var p Person if err := json.Unmarshal(b, &p); err != nil { fmt.Println(err) } fmt.Println(p.Name, p.Age, p.Nickname)

v, _ := json.Marshal(p)
fmt.Println(string(v))

}

unmarhalを改造したい場合、UnmarsalJSONという関数を作って処理を記載すればいい。   

package main

import ( "encoding/json" "fmt" )

type T struct{}

type Person struct { Name string json:"name,omitempty" Age int json:"age,omitempty" Nickname []string json:"nicknames,omitempty" T *T json:"T,omitempty" }

func (p *Person) UnmarshalJSON(b byte) error { type Person2 struct { Name string } var p2 Person2 err := json.Unmarshal(b, &p2) if err != nil { fmt.Println(err) } p.Name = p2.Name + "!" return err }

func main() { b := byte({"name":"mike","age":20,"nicknames":{}}) var p Person if err := json.Unmarshal(b, &p); err != nil { fmt.Println(err) } fmt.Println(p.Name, p.Age, p.Nickname)

v, _ := json.Marshal(p)
fmt.Println(string(v))

}


## 読書
https://note.com/shosagyo/n/nb1093747c7d3