【回転】Golang下のencoding関連モジュール使用/go符号化
変換元:https://www.jianshu.com/p/772ca3c6c7ed
encoding/jsonモジュールの使用
パッケージ名:
marshalとunmarshal
一般的なメソッド関数:
注意すべき点:
例:
decodeとencode
関連関数とメソッド:
decodeの例:
encoding/hexモジュールの使用
Hexパケットは主に16進数の文字列の主要関数を符号化および復号するために使用される.
例:
encoding/gobパッケージの使用
gobパケットは、主にバイナリのバイトストリーム間で符号化および復号化されるものを管理するために使用される.1つの典型的な使用例は、
1.アナログネットワークにおけるバイトストリーム変換
例として、2つの構造体P,Qを定義し、前者はgobが1つのネットワークで符号化(encoder)するデータ構造であり、後者は復号(decoder)するデータ構造である.
実行効果:
2.カスタムEncodeおよびDecodeメソッドツールによる値の転送
インタフェースによる構造体変数のプライベート変数の変換
出力例:
3.gobパケットを使用してインタフェースタイプのデータを転送する
encoding/jsonモジュールの使用
パッケージ名:
encoding/json
プログラム開発中に最も一般的なのは、文字列とjson
間の変換です.Golang
では、変換媒体としてjson
文字列の構造体を定義する必要がある.marshalとunmarshal
一般的なメソッド関数:
// v json []byte
func Marshal(v interface{}) ([]byte, error)
// json
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
// json []byte, v
func Unmarshal(data []byte, v interface{}) error
注意すべき点:
/*
json , struct tag :
(1) tag "-", JSON
(2)tag , json
(3)tag "omitempty" , , json
(4) bool,string,int,int64 , tag ",string" , json json
Marshal , :
(1)JSON string key, map, map[string]T
(2)Channel,complex function JSON
(3) , json
(4) , null
*/
例:
# golang json
$ cat marshal-test.go
package main
import (
"fmt"
"encoding/json"
_ "bytes"
"os"
)
type Serverslice struct{
Servers []Server `json:"servers"`
}
type Server struct{
ServerName string `json:"servername"`
ServerIP string `json:"serverip,omitempty"`
}
func main() {
var s Serverslice
//func append(slice []Type, elems ...Type) []Type
s.Servers = append(s.Servers,Server{ServerName:"Beijing",ServerIP:"10.0.0.1"})
s.Servers = append(s.Servers,Server{ServerName:"Xi'an",ServerIP:"10.0.0.2"})
//slice [{},{}] slice json
ss := []Server{{"Beijing","172.0.0.1"},{"Shanghai","172.0.0.2"}}
b,err := json.Marshal(s)
if err != nil { os.Exit(1) }
fmt.Println(string(b))
bb,err := json.MarshalIndent(ss,""," ")
if err == nil { fmt.Println(string(bb)) }
}
// []struct
// []struct
$ go run marshal-test.go
{"servers":[{"servername":"Beijing","serverip":"10.0.0.1"},{"servername":"Xi'an","serverip":"10.0.0.2"}]}
[
{
"servername": "Beijing",
"serverip": "172.0.0.1"
},
{
"servername": "Shanghai",
"serverip": "172.0.0.2"
}
]
# json
$ cat unmarshal.go
package main
import (
"fmt"
"encoding/json"
)
type Server struct {
ServerName string `json:"servername"`
ServerIP string `json:"serverip"`
}
// slice
type Serverslice struct{
Servers []Server
}
func main() {
// json
str := `{"servers":[{"servername":"Beijing","serverip":"10.0.0.1"},{"servername":"Xi'an","serverip":"10.0.0.2"}]}`
//func Unmarshal(data []byte, v interface{}) error
// , json
var s Serverslice
// json s ( , )
// json []byte ( )
if err := json.Unmarshal([]byte(str),&s); err == nil {
fmt.Println(s)
fmt.Println(s.Servers)
fmt.Println(s.Servers[0].ServerName,s.Servers[1].ServerName)
}
}
decodeとencode
関連関数とメソッド:
// json
type Decoder struct {
// contains filtered or unexported fields
}
// Decoder
func NewDecoder(r io.Reader) *Decoder
//Decoder
func (dec *Decoder) Buffered() io.Reader
func (dec *Decoder) Decode(v interface{}) error
func (dec *Decoder) More() bool
func (dec *Decoder) Token() (Token, error)
func (dec *Decoder) UseNumber()
// json
type Encoder struct {
// contains filtered or unexported fields
}
// Encoder
func NewEncoder(w io.Writer) *Encoder
// json v , Marshal
func (enc *Encoder) Encode(v interface{}) error
func (enc *Encoder) SetEscapeHTML(on bool)
func (enc *Encoder) SetIndent(prefix, indent string)
decodeの例:
$ cat decoder.go
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"strings"
)
func main() {
const jsonStream = `
{"Name": "Ed", "Text": "Knock knock."}
{"Name": "Sam", "Text": "Who's there?"}
{"Name": "Ed", "Text": "Go fmt."}
{"Name": "Sam", "Text": "Go fmt who?"}
{"Name": "Ed", "Text": "Go fmt yourself!"}
`
type Message struct {
Name, Text string
}
// Decoder
//func NewDecoder(r io.Reader) *Decoder
dec := json.NewDecoder(strings.NewReader(jsonStream))
for {
var m Message
// decoder Decide v
//func (dec *Decoder) Decode(v interface{}) error
//
if err := dec.Decode(&m); err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
fmt.Printf("%s: %s
", m.Name, m.Text)
}
}
$ go run decode.go
Ed: Knock knock.
Sam: Who's there?
Ed: Go fmt.
Sam: Go fmt who?
Ed: Go fmt yourself!
encoding/hexモジュールの使用
Hexパケットは主に16進数の文字列の主要関数を符号化および復号するために使用される.
// src []byte dst( DecodedLen(len(src))) , dst
func Decode(dst, src []byte) (int, error)
// 16 []byte
func DecodeString(s string) ([]byte, error)
//x byte , x/2
func DecodedLen(x int) int
// data dump , `hexdump -C`
func Dump(data []byte) string
func Dumper(w io.Writer) io.WriteCloser
// src dst ( EncodedLen(len(src)) )
func Encode(dst, src []byte) int
// []byte 16
func EncodeToString(src []byte) string
// , n 2
func EncodedLen(n int) int
例:
$ cat hex.go
package main
import (
"encoding/hex"
"fmt"
)
func Something() {
//func EncodeToString(src []byte) string byte 16
src := []byte("hello")
fmt.Println(src) //[104 101 108 108 111]
encodeStr := hex.EncodeToString(src) //68656c6c6f 16
fmt.Println(encodeStr)
//func Encode(dst, src []byte) int
//func EncodedLen(n int) int
Welcome := []byte("Gopher!")
Wdest := make([]byte, hex.EncodedLen(len(Welcome)))
num := hex.Encode(Wdest, Welcome)
fmt.Println(Wdest, num) //num=14
//func DecodeString(s string) ([]byte, error) 16 byte
decodeStr, _ := hex.DecodeString(encodeStr)
fmt.Println(string(decodeStr))
//func DecodedLen(x int) int x byte , x/2
//func Decode(dst, src []byte) (int, error) byte src byte dst , dst
test := []byte("48656c6c6f20476f7068657221")
dest := make([]byte, hex.DecodedLen(len(test))) //
num, err := hex.Decode(dest, test) // 16 byte[] ,
if err != nil {
return
}
fmt.Println(num, dest[:num], string(dest), len(dest), cap(dest)) // print 13
//func Dump(data []byte) string // hex dump linux "hexdump -C filename"
content := []byte("Go is an open source programming language.")
fmt.Println(hex.Dump(content))
}
func main() {
Something()
}
$ go run hex.go
[104 101 108 108 111]
68656c6c6f
[52 55 54 102 55 48 54 56 54 53 55 50 50 49] 14
hello
13 [72 101 108 108 111 32 71 111 112 104 101 114 33] Hello Gopher! 13 13
00000000 47 6f 20 69 73 20 61 6e 20 6f 70 65 6e 20 73 6f |Go is an open so|
00000010 75 72 63 65 20 70 72 6f 67 72 61 6d 6d 69 6e 67 |urce programming|
00000020 20 6c 61 6e 67 75 61 67 65 2e | language.|
encoding/gobパッケージの使用
gobパケットは、主にバイナリのバイトストリーム間で符号化および復号化されるものを管理するために使用される.1つの典型的な使用例は、
net/rpc
パケットを使用して、リモート・プロシージャ呼び出し(RPC
)におけるパラメータおよび結果を送信することである.import "encoding/gob"
1.アナログネットワークにおけるバイトストリーム変換
例として、2つの構造体P,Qを定義し、前者はgobが1つのネットワークで符号化(encoder)するデータ構造であり、後者は復号(decoder)するデータ構造である.
package main
/*
`encoding/gob` , (encoder), , (decoder)
*/
import (
"bytes"
"encoding/gob"
"fmt"
"log"
)
type P struct {
X, Y, Z int
Name string
}
type Q struct {
X, Y *int32
Name string
}
func main() {
// encoder decoder.t encoder decoder ,
var network bytes.Buffer // buffer ( )
enc := gob.NewEncoder(&network) //
dec := gob.NewDecoder(&network) //
/*
//NewDecoder decoder , Decoder
func NewDecoder(r io.Reader) *Decoder
// Decoder
func (dec *Decoder) Decode(e interface{}) error
func (*Decoder) DecodeValue
//NewEncoder encoder , Encoder
func NewEncoder(w io.Writer) *Encoder
// Encoder
func (enc *Encoder) Encode(e interface{}) error
func (enc *Encoder) EncodeValue(value reflect.Value) error
*/
// enc
// enc.Encode
err := enc.Encode(P{6, 6, 8, "xxbandy.github.io"})
if err != nil {
log.Fatal("encode error:", err)
}
err = enc.Encode(P{1024, 2048, 1000, "BG "})
if err != nil {
log.Fatal("encode error:", err)
}
// dec
// , (&network) Q q
var q Q
err = dec.Decode(&q)
if err != nil {
log.Fatal("decode error 1:", err)
}
fmt.Printf("%q: {%d, %d}
", q.Name, *q.X, *q.Y)
err = dec.Decode(&q)
if err != nil {
log.Fatal("decode error 2:", err)
}
fmt.Printf("%q: {%d, %d}
", q.Name, *q.X, *q.Y)
}
実行効果:
$ go run simple-encoder-decoder.go
"xxbandy.github.io": {6, 6}
"BG ": {1024, 2048}
2.カスタムEncodeおよびDecodeメソッドツールによる値の転送
インタフェースによる構造体変数のプライベート変数の変換
package main
import (
"bytes"
"encoding/gob"
"fmt"
"log"
)
// Vector , , `gob`
// BinaryMarshal/BinaryUnmarshal .
// `encoding`
// `GobEncode/GobDecoder`
type Vector struct {
x, y, z int
}
// Vector MarshalBinary
func (v Vector) MarshalBinary() ([]byte, error) {
// A simple encoding: plain text.
//
var b bytes.Buffer
fmt.Fprintln(&b, v.x, v.y, v.z)
return b.Bytes(), nil
}
// Vector UnmarshalBinary ,
func (v *Vector) UnmarshalBinary(data []byte) error {
b := bytes.NewBuffer(data)
_, err := fmt.Fscanln(b, &v.x, &v.y, &v.z)
return err
}
// encoding decoding
func main() {
// buffer
var network bytes.Buffer
// encoder
enc := gob.NewEncoder(&network)
// Vector ,
// : Vector MarshalBinary UnmarshalBinary
err := enc.Encode(Vector{3, 4, 5})
if err != nil {
log.Fatal("encode:", err)
}
// (decoder)
dec := gob.NewDecoder(&network)
var v Vector
err = dec.Decode(&v)
if err != nil {
log.Fatal("decode:", err)
}
fmt.Println(v)
}
出力例:
$ go run gob-EncoderDecoder.go
{3 4 5}
3.gobパケットを使用してインタフェースタイプのデータを転送する
gob
パケットを使用してインタフェースタイプデータを符号化、復号、伝送するには、gob.Register(value interface{})
を使用して指定されたタイプデータを登録する必要がある./**
* @File Name: gob-interface.go
* @Author: xxbandy @http://xxbandy.github.io
* @Email:
* @Create Date: 2018-03-12 14:03:10
* @Last Modified: 2018-03-12 14:03:23
* @Description:
*/
package main
import (
"bytes"
"encoding/gob"
"fmt"
"log"
"math"
)
type Point struct {
X, Y int
}
//
func (p Point) Hypotenuse() float64 {
return math.Hypot(float64(p.X), float64(p.Y))
}
// , ,
type Pythagoras interface {
Hypotenuse() float64
}
//
//
func main() {
//
var network bytes.Buffer
// encoder decoder
//
// func Register(value interface{})
gob.Register(Point{})
// encoder
enc := gob.NewEncoder(&network)
for i := 1; i <= 3; i++ {
interfaceEncode(enc, Point{3 * i, 4 * i})
}
// decoder
dec := gob.NewDecoder(&network)
for i := 1; i <= 3; i++ {
result := interfaceDecode(dec)
fmt.Println(result.Hypotenuse())
}
}
// interfaceEncode encoder
func interfaceEncode(enc *gob.Encoder, p Pythagoras) {
// ,
// , p,
err := enc.Encode(&p)
if err != nil {
log.Fatal("encode:", err)
}
}
// interfaceDecode
// Pythagoras
func interfaceDecode(dec *gob.Decoder) Pythagoras {
// decode (Point{} gob.Register() )
//
var p Pythagoras
err := dec.Decode(&p)
if err != nil {
log.Fatal("decode:", err)
}
return p
}
$ go run gob-interface.go
5
10
15