Go 中序列化与反序列化

以 JSON 格式为例,对 Go 的 struct 进行序列化与反序列化 import ( "encoding/json" "fmt" ) type Person struct { Name string Age int } func main() { // struct to json person := Person{ Name: "Tom", Age: 10, } marshaled, err := json.Marshal(person) if err != nil { fmt.Printf("Error marsaling %s\n", err) return } s := string(marshaled) fmt.Printf("Type: %T, Value:%+v\n", s, s) } // json to struct person = Person{} if err = json.Unmarshal([]byte(strJSON), &person); err != nil { fmt.Printf("Error unmarsaling %s\n", err) return } fmt.Printf("Type: %T, Value:%+v\n", person, person) } 也可以对 map 类型进行序列化与反序列化 func mapToJson(m map[string]interface{}) ([]byte, error) { marshaled, err := json.Marshal(m) if err != nil { fmt.Println("json encode failed, err:", err) } return marshaled, nil } func jsonToMap(b []byte) (map[string]interface{}, error) { var m map[string]interface{} err := json.Unmarshal(b, &m) if err != nil { fmt.Println("json decode failed, err:", err) return nil, err } return m, nil } 但是 encoding/json 对于 map[string]interface 中的数字类型(整型、浮点型等)都序列化成 float64 类型。 ...

January 2, 2024

Go net 包的使用

net 包中定义了以下基本接口 type Conn interface { Read(b []byte) (n int, err error) Write(b []byte) (n int, err error) Close() error LocalAddr() Addr RemoteAddr() Addr SetDeadline(t time.Time) error SetReadDeadline(t time.Time) error SetWriteDeadline(t time.Time) error } type PacketConn interface { ReadFrom(b []byte) (n int, addr Addr, err error) WriteTo(b []byte, addr Addr) (n int, err error) Close() error LocalAddr() Addr SetDeadline(t time.Time) error SetReadDeadline(t time.Time) error SetWriteDeadline(t time.Time) error } IP 主要类型 net.IP 用 string 创建 net.IP 对象,它实际是一个 []byte 类型 ip := net.ParseIP("127.0.0.1") net.IPAddr 创建 net.IPAddr 对象,是 net 包中许多函数和方法的操作对象 ipAddr := net.IPAddr{ IP: ip, } net.IPMask 可以用 4 个 bytes 创建一个 IPv4 的掩码 ipmask := net.IPv4Mask(255, 255, 0, 0) net.IPNet net.IPNet 网段由 IP 和 IPMask 组成 mask := net.IPv4Mask(byte(255), byte(255), byte(255), byte(0)) ip := net.ParseIP("192.168.1.125").Mask(mask) in := &net.IPNet{ip, mask} fmt.Println(in) // 192.168.1.0/24 连接 // 连接 func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) // example remoteAddr := net.IPAddr{ IP: net.ParseIP("1.2.3.4"), } conn, err := net.DialIP("ip4:icmp", nil, &remoteAddr) // 监听 func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) // example localAddr := net.IPAddr{ IP: net.ParseIP("127.0.0.1"), } net.ListenIP("ip4:icmp", &localAddr) TCP 解析 TCP Address ...

December 31, 2023

Go Cookbook

References How to Write Go Code Effective Go Awesome Go Install 下载安装 rm -rf /usr/local/go && tar -C /usr/local -xzf go1.20.2.linux-amd64.tar.gz 添加环境变量 export GOPATH=/data/username/go # 修改 GOPATH,默认是 $HOME/go export GO111MODULE=on # 默认开启 go module export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin # 添加环境变量 查看环境变量 go env Go Modules 开启go modules go env -w GO111MODULE="auto" # 如果无法访问proxy.golang.org,需要修改proxy go env -w GOPROXY=https://goproxy.cn,direct # 公司proxy:https://goproxy.woa.com export GOPROXY="https://yizhenchen:vm4UIuF1@goproxy.woa.com,direct" export GOPRIVATE="" export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4" export no_proxy=$no_proxy",goproxy.woa.com" 使用 # 初始化包 go mod init example/user/hello # build and install go install example/user/hello # 自动检测依赖包 go mod tidy 配置境内源 ...

January 1, 2000

Go Language

Code Reference gotemplate.go: package main import ( "fmt" ) const c = "C" var v int = 5 type T struct{} func init() { // initialization of package } func main() { var a int Func1() // ... fmt.Println(a) } func (t T) Method1() { // ... } func Func1() { // exported function Func1 // ... } 变量与常量 Assignment // declare and init var s1 string = "hello" var s2 = "world" // 简写,有初始值时可省略类型 s3 := "hello world" // 简写 var i1, i2 int = 1, 2 // 同时声明多个变量 var i3, s4 = 1, "2" // 有初始值时可省略类型 var i4 = 4 i5 := 5 // := 结构不能在函数外使用 // declare without initiation var s0 string // s0 = "" var i0 int // i0 = 0 var b0 bool // b0 = false Constants const s string = "constant" const n = 500000000 // 数值常量可以是任意精度,没有类型 const d = 3e20 / n // 常量不能用 := 语法声明 Enum 常量还可以用作枚举: ...

January 1, 2000

Go Packages

Utils godetenv Github - godotenv Go 每日一库 - godotenv 读取同目录下 .env 文件 name=Tom age=18 example import "github.com/joho/godotenv" func main() { err := godotenv.Load() if err != nil { log.Fatal(err) } fmt.Println("name: ", os.Getenv("name")) fmt.Println("age: ", os.Getenv("age")) } // 也可以加载其他文件 // 如果多个文件出现同一个 key,先出现的优先后出现的不生效 godotenv.Load("common", "dev.env") 也可以加载 YAML 文件 name: awesome web version: 0.0.1 # os.Getenv("name") 一般有多个环境文件:.env.dev、.env.test、env.production,可以用以下代码切换 env := os.Getenv("APP_ENV") if env == "" { env = "dev" } err := godotenv.Load(".env." + env) if err != nil { log.Fatal(err) } err = godotenv.Load() if err != nil { log.Fatal(err) } fmt.Println("name: ", os.Getenv("name")) fmt.Println("version: ", os.Getenv("version")) fmt.Println("database: ", os.Getenv("database")) CLI flag 用于解析命令行参数 ...

January 1, 2000

Go Standard Lib

fmt Format specifiers: %t: boolean %c: character %U: unicode code point %s: strings or []bytes %q: quoted string %#q: quoted string with backquotes %b: bit representation %d: integers (base 10) %o: octal (base 8) notation %x/%X: hexadecimal (base 16) notation %f: floats %g: complex %e: scientific notation %p: pointers (hexadecimal address with prefix 0x) %v: default format, when String() exists, this is used. %+v: gives a complete output of the instance with its fields %#v: gives us a complete output of the instance with its fields and qualified type name %T gives us the complete type specification %%: if you want to print a literal % sign type user struct { name string } func main() { u := user{"tang"} //Printf 格式化输出 fmt.Printf("%+v\n", u) //格式化输出结构 fmt.Printf("%#v\n", u) //输出值的 Go 语言表示方法 fmt.Printf("%T\n", u) //输出值的类型的 Go 语言表示 fmt.Printf("%t\n", true) //输出值的 true 或 false fmt.Printf("%b\n", 1024) //二进制表示 fmt.Printf("%c\n", 11111111) //数值对应的 Unicode 编码字符 fmt.Printf("%d\n", 10) //十进制表示 fmt.Printf("%o\n", 8) //八进制表示 fmt.Printf("%q\n", 22) //转化为十六进制并附上单引号 fmt.Printf("%x\n", 1223) //十六进制表示,用a-f表示 fmt.Printf("%X\n", 1223) //十六进制表示,用A-F表示 fmt.Printf("%U\n", 1233) //Unicode表示 fmt.Printf("%b\n", 12.34) //无小数部分,两位指数的科学计数法6946802425218990p-49 fmt.Printf("%e\n", 12.345) //科学计数法,e表示 fmt.Printf("%E\n", 12.34455) //科学计数法,E表示 fmt.Printf("%f\n", 12.3456) //有小数部分,无指数部分 fmt.Printf("%g\n", 12.3456) //根据实际情况采用%e或%f输出 fmt.Printf("%G\n", 12.3456) //根据实际情况采用%E或%f输出 fmt.Printf("%s\n", "wqdew") //直接输出字符串或者[]byte fmt.Printf("%q\n", "dedede") //双引号括起来的字符串 fmt.Printf("%x\n", "abczxc") //每个字节用两字节十六进制表示,a-f表示 fmt.Printf("%X\n", "asdzxc") //每个字节用两字节十六进制表示,A-F表示 fmt.Printf("%p\n", 0x123) //0x开头的十六进制数表示 } io studygolang - io — 基本的 IO 接口 ...

January 1, 2000