golang常用方法积累
日志记录
- log日志包
func main() {
log.Println("helloworld:","https://blog.csdn.net/weixin_43819222")
log.Printf("helloworld:%s\n","https://blog.csdn.net/weixin_43819222")
}
Println
与Printf
的区别:
1.Println
:可以打印出字符串,和变量
2.Printf
:只可以打印出格式化的字符串,可以输出字符串类型的变量,不可以输出整形变量和整形
3.Sprintf
:用传入的格式化规则符将传入的变量格式化,(终端中不会有显示),返回为 格式化后的字符串(常用于赋值)
- 定制抬头信息
func init(){
log.SetFlags(log.Ldate|Lshortfile)
}
///
选项常量
const (
Ldate = 1 << iota //日期示例: 2009/01/23
Ltime //时间示例: 01:23:23
Lmicroseconds //毫秒示例: 01:23:23.123123.
Llongfile //绝对路径和行号: /a/b/c/d.go:23
Lshortfile //文件和行号: d.go:23.
LUTC //日期时间转为0时区的
LstdFlags = Ldate | Ltime //Go提供的标准抬头信息
)
设置日志前缀
func init(){
log.SetPrefix("【duanyiwen】")
log.SetFlags(log.LstdFlags | log.Lshortfile |log.LUTC)
}
///
【duanyiwen】2017/04/29 05:53:26 main.go:11: helloworld: https://blog.csdn.net/weixin_43819222
【duanyiwen】2017/04/29 05:53:26 main.go:12: helloworld:duanyiwen
- 定制日志
var (
Info *log.Logger
Warning *log.Logger
Error * log.Logger
)
将ERROR级输出到文本
func init(){
errFile,err:=os.OpenFile("errors.log",os.O_CREATE|os.O_WRONLY|os.O_APPEND,0666)
if err!=nil{
log.Fatalln("打开日志文件失败:",err)
}
Info = log.New(os.Stdout,"Info:",log.Ldate | log.Ltime | log.Lshortfile)
Warning = log.New(os.Stdout,"Warning:",log.Ldate | log.Ltime | log.Lshortfile)
Error = log.New(io.MultiWriter(os.Stderr,errFile),"Error:",log.Ldate | log.Ltime | log.Lshortfile)
}
全部归到文本
LogFile,err:=os.OpenFile("duanyiwen.log",os.O_CREATE|os.O_WRONLY|os.O_APPEND,0666)
Info = log.New(io.MultiWriter(os.Stderr,LogFile),"Info:",log.Ldate | log.Ltime | log.Lshortfile)
Warning = log.New(io.MultiWriter(os.Stderr,LogFile),"Warning:",log.Ldate | log.Ltime | log.Lshortfile)
Error = log.New(io.MultiWriter(os.Stderr,LogFile),"Error:",log.Ldate | log.Ltime | log.Lshortfile)
HTTP请求
- Get请求
package main
import (
"fmt",
"io/ioutil",
"net/http"
)
func main() {
resp, err := http.Get("http://baidu.com")
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
fmt.Println(resp.StatusCode)
if resp.StatusCode == 200 {
fmt.Println("ok")
}
}
- Get变量入参
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
func main() {
params := url.Values()
Url, err := url.Parse("http://baidu.com")
if err != nil {
return
}
params.Set("name","Paul_Chan")
params.Set("age","26")
Url.RawQuery = params.Encode()//解码中文
urlPath := Url.String()
fmt.Println(urlPath) // https://www.baidu.com?age=26&name=Paul_chan
resp,err := http.Get(urlPath)
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
- 解析json类型的返回结果
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type result struct {
Args string `json:"args"`
Headers map[string]string `json:"headers"`
Origin string `json:"origin"`
Url string `json:"url"`
}
func main() {
resp, err := http.Get("http://baidu.com")
if err != nil {
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
var res result
_ = json.Unmarshal(body,&res)
fmt.Printf("%#v",res)
//%#v 用Go的语法打印。
//比如main.People{name:”sam”, phone:main.Phone{mobile:”12345”, office:”67890”}}
}
- Get添加请求头
func main() {
client := &http.Client{}
req,_ := http.NewRequest("GET","http://xxx.com",nil)
req.Header.Add("name","Paul_Chan")
req.Header.Add("age","26")
resp,_ := client.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf(string(body))
}
- Post请求
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
//表单提交
func main() {
urlValues := url.Values{}
urlValues.Add("name","Paul_Chan")
urlValues.Add("age","26")
resp, _ := http.PostForm("http://xxx.com/post",urlValues)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
//“text/html”提交
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
func main() {
urlValues := url.Values{
"name":{"Paul_Chan"},
"age":{"26"},
}
reqBody:= urlValues.Encode()
resp, _ := http.Post("http://baidu.com/post", "text/html",strings.NewReader(reqBody))
body,_:= ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
- POST-json
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
client := &http.Client{}
data := make(map[string]interface{})
data["name"] = "zhaofan"
data["age"] = "23"
bytesData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST","http://httpbin.org/post",bytes.NewReader(bytesData))
req.Header.Add("Content-Type", "application/json")
resp, _ := client.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
///不要client,使用http.post
func main() {
data := make(map[string]interface{})
data["name"] = "zhaofan"
data["age"] = "23"
bytesData, _ := json.Marshal(data)
resp, _ := http.Post("http://httpbin.org/post","application/json", bytes.NewReader(bytesData))
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
- POST-Client提交表单
func LogIn2() (*http.Response, error) {
data := url.Values{}
data.Set("name", name)
data.Set("password", password)
data.Set("autologin", "1")
data.Set("enter", "Sign in")
r, _ := http.NewRequest(POST, login_url, strings.NewReader(data.Encode()))
r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(r)
if err != nil {
Error.Fatalln(err)
return nil, err
}
return resp, nil
}
- Cookies保存
package main
import (
"fmt"
"net/http"
"net/http/cookiejar"
)
func main() {
jar, _ := cookiejar.New(nil)
timeOut := time.Duration(1 * time.Second)
fmt.Println("Start Request Server")
client := &http.Client{}
client.Jar = jar
client.Timeout = timeOut
url := "http://127.0.0.1:8889/test"
req, _ := http.NewRequest("GET", url, nil)
//第一次发请求
client.Do(req)
fmt.Printf("第一次 %s \n", req.Cookies())
}
字符处理
- 格式化赋值
b := "hello world"
a := fmt.Sprintf("%s",b)
fmt.Println(a)
- 查询变量类型
- fmt
fmt.Printf("%s类型为%T\n",c,c)
- 自定义
import "fmt" func main() { v := "hello world" fmt.Println(typeof(v)) } func typeof(v interface{}) string { return fmt.Sprintf("%T", v) }
- 反射
import ( "reflect" "fmt" ) func main() { v := "hello world" fmt.Println(typeof(v)) } func typeof(v interface{}) string { return reflect.TypeOf(v).String() }
- 字符切割
import (
"strings"
"fmt"
)
func main() {
b := "hello:world"
c := strings.Split(b,":")
fmt.Printf("%s类型为%T\n",c,c)
}
- 定义变量
/[]string类型
func main() {
a := [2]string{"111","222"}
fmt.Println(a)
}
[]byte
func main() {
a := []byte("Hello World!")
fmt.Println(a)
}
strings库
fmt.Println(strings.HasPrefix(s3, "a")) //判断前缀
fmt.Println(strings.HasSuffix(s3, "0")) //判断后缀
fmt.Println(strings.Contains(s3, "9")) //字符串包含关系
fmt.Println(strings.Index(s3, "0")) //判断子字符串或字符在父字符串中出现的位置(索引)
fmt.Println(strings.LastIndex(s3, "0")) //最后出现位置的索引
fmt.Println(strings.Replace(s3,"0","1",-1))//如果 n = -1 则替换所有字符串
fmt.Println(strings.Count(s3,"0"))//出现的非重叠次数
fmt.Println(strings.Repeat(s3,2))//重复字符串
fmt.Println(strings.ToLower(s3))//修改字符串大小写
fmt.Println(strings.ToUpper(s3))//修改字符串大小写
fmt.Println(strings.TrimSpace(s3))//修剪字符串 去掉开头和结尾空格
fmt.Println(strings.Trim(strings.TrimSpace(s3),"a"))//修剪字符串 去掉开头和结尾字符串
正则匹配
- 判断是否匹配
package main;
import (
// "bytes"
"fmt"
"regexp"
// "strings"
)
func main() {
match,_ := regexp.MatchString("H(.*)d!","Hello World!")
fmt.Println(match)
//true
match2,_ := regexp.Match("H(.*)d!",[]byte("Hello World!"))
fmt.Println(match2)
//true
rex, _ := regexp.Compile("H(.*)d!")
fmt.Println(rex.MatchString("Hello World!"))
//true
}
- 返回匹配字符
func main() {
rex, _ := regexp.Compile("H(.*)d!")
fmt.Println(rex.MatchString("Hello World!"))
text := "Hello World! Hworld!"
//返回匹配项目
fmt.Println(rex.FindString(text))
//返回匹配项目起始索引
fmt.Println(rex.FindStringIndex(text))
//返回全局匹配和局部匹配(局部匹配即精确匹配括号内的)
fmt.Println(rex.FindStringSubmatch(text))
//返回全局匹配和局部匹配的索引
fmt.Println(rex.FindStringSubmatchIndex(text),len(rex.FindStringSubmatchIndex(text)))
//返回所有匹配项
fmt.Println(rex.FindAllString(text, -1),len(rex.FindAllString(text, -1)))
//返回所有全局匹配和局部匹配的字符索引
rex.FindAllStringSubmatchIndex(text,-1)
//入参正整数来限制匹配数量
text2 := "Hello World! Held! Hellowrld! world Haaaaaad"
res, _ := regexp.Compile("H([a-z]+)d!")
fmt.Println(res.FindAllString(text2, 2)) //-1即所有,1,2,3次
}
- 替换匹配字符
func main() {
rex, _ := regexp.Compile("H([a-z]+)d!")
result := rex.ReplaceAllString("Hello World! Held! world","html")
fmt.Println(result)
//将匹配项进行大小写转换
in := []byte("Hello World! Held! world")
out := rex.ReplaceAllFunc(in,bytes.ToUpper)
fmt.Println(string(out))
//全部转大写
c := []byte("aaaaasss dddff ggvv adas")
fmt.Println(string(bytes.ToUpper(c)))
a := "aaaaasss dddff ggvv adas"
fmt.Println(strings.ToUpper(a))
}
类型定义
不定参数类型定义
- 定义python中的print函数
import (
"time"
"fmt"
)
func print(args interface{}) {
fmt.Println(args)
}
func main() {
timeStr := time.Now().Format("2006-01-02 02:02:03")
print(timeStr)
print("222222")
}
var
// 初始化多个同类型变量
var name1, name2, name3 string = "name1", "name2", "name3"
//初始化多个不同类变量
var (
name string = "keyworkd"
count int = 2
)
//省略变量类型
var name1, name2, name3 = "name1", "name2", "name3"
const
const可以全局,局部定义。常量不可赋值修改
map
package main
import(
"fmt"
// "time"
// "runtime"
)
func typeof(v interface{}) string {
return fmt.Sprintf("%T", v)
}
func main() {
m := make(map[string]int)
m["k"] = 7
m["b"] = 7
v := m["k"]
fmt.Println(m)
fmt.Println("v:",v)
fmt.Println(len(m))
delete(m,"k")
fmt.Println(m,typeof(m))
}
map转json
import(
"fmt"
"encoding/json"
// "time"
// "runtime"
)
func main() {
s := []map[string]interface{}{}
m1 := map[string]interface{}{"name":"John","age":10}
m2 := map[string]interface{}{"name":"Alex","age":12}
s = append(s, m1, m2)
s = append(s, m2)
fmt.Println("s:", s)
b, err := json.Marshal(s)
if err != nil {
fmt.Println("json.Marshal failed:",err)
return
}
fmt.Println("b:", string(b))
}
json
使用高性能json包:jsonitor
学习自:https://www.jianshu.com/p/f797343eb04f
go get github.com/json-iterator/go
import (
"fmt"
"github.com/json-iterator/go" // 引入
"os"
"strings"
)
type ColorGroup struct {
ID int
Name string
Colors []string
}
type Animal struct {
Name string
Order string
}
func main() {
// ================= 序列化 =====================
group := ColorGroup{
ID: 1,
Name: "Reds",
Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
}
b, err := jsoniter.Marshal(group)
bb, err := jsoniter.MarshalIndent(group, "", " ")
if err != nil{
fmt.Println("error: ", err)
}
os.Stdout.Write(b)
fmt.Println()
os.Stdout.Write(bb)
fmt.Println()
// =================== Deconde 解码 =================
jsoniter.NewDecoder(os.Stdin).Decode(&group)
fmt.Println(group)
//encoder := jsoniter.NewEncoder(os.Stdout)
//encoder.SetEscapeHTML(true)
//encoder.Encode(bb)
//fmt.Println(string(bb))
// =================== 反序列化 =======================
var jsonBlob = []byte(`[
{"Name": "Platypus", "Order": "Monotremata"},
{"Name": "Quoll", "Order": "Dasyuromorphia"}
]`)
var animals []Animal
if err := jsoniter.Unmarshal(jsonBlob, &animals); err != nil{
fmt.Println("error: ", err)
}
fmt.Printf("the unmarshal is %+v", animals)
// ======================= 流式 ========================
fmt.Println()
// 序列化
stream := jsoniter.ConfigFastest.BorrowStream(nil)
defer jsoniter.ConfigFastest.ReturnStream(stream)
stream.WriteVal(group)
if stream.Error != nil{
fmt.Println("error: ", stream.Error)
}
os.Stdout.Write(stream.Buffer())
fmt.Println()
// 反序列化
iter := jsoniter.ConfigFastest.BorrowIterator(jsonBlob)
defer jsoniter.ConfigFastest.ReturnIterator(iter)
iter.ReadVal(&animals)
if iter.Error != nil{
fmt.Println("error: ", iter.Error)
}
fmt.Printf("%+v", animals)
fmt.Println()
// ====================其他操作===================
// get
val := []byte(`{"ID":1,"Name":"Reds","Colors":
{"c":"Crimson","r":"Red","rb":"Ruby","m":"Maroon","tests":["tests_1","tests_2","tests_3","tests_4"]}}`)
fmt.Println(jsoniter.Get(val, "Colors").ToString())
fmt.Println("the result is " , jsoniter.Get(val, "Colors","tests",0).ToString())
// fmt.Println(jsoniter.Get(val, "colors", 0).ToString())
fmt.Println()
hello := MyKey("hello")
output, _ := jsoniter.Marshal(map[*MyKey]string{&hello: "world"})
fmt.Println(string(output))
obj := map[*MyKey]string{}
jsoniter.Unmarshal(output, &obj)
for k, v := range obj{
fmt.Println(*k," = ", v)
}
}
// 自定义类型
// 序列化: 需要实现MarshellText
type MyKey string
func (m *MyKey) MarshalText() ([]byte, error){
// return []byte(string(*m)) , nil // 针对序列化的内容不做任何调整
return []byte(strings.Replace(string(*m), "h","H",-1)), nil
}
func(m *MyKey) UnmarshalText(text []byte) error{
*m = MyKey(text[:]) // 针对text不做处理
return nil
}
package main
import (
"fmt"
"encoding/json"
)
type FamilyRequestBody struct {
Family string `json:"family"`
}
type DataRequestBody struct {
Family FamilyRequestBody `json:"family"`
}
type EventRequestBody struct {
Account string `json:"account"`
Player string `json:"player"`
Count int `json:"count"`
}
type TeamRequestBody struct {
Account string `json:"account"`
Team string `json:"team"`
}
type PlayerRequestBody struct {
Account string `json:"account"`
Team string `json:"team"`
Player string `json:"player"`
Data DataRequestBody `json:"data"`
}
func main() {
l := PlayerRequestBody{
Account: "my-account",
Team: "12345",
Player: "23424234",
Data: DataRequestBody{FamilyRequestBody{Family: "12345"}},
}
fmt.Printf("%#v,%T", l, l)
fmt.Println(l)
bb, _ := json.Marshal(l)
fmt.Println(string(bb))
}
type
go结构体生成:http://json2struct.mervine.net/
- 定义嵌套结构
type ColorGroup struct {
ID int
Name string
Colors []string
}
type Animal struct {
Name string
Order string
}
type Data struct {
data0 map[string]interface{}
data1 string
}
package main
import "fmt"
type s1 struct {
ID string
s2 s2
s3 s3
}
type s2 struct {
WebSiteName string
URL string
}
type s3 struct {
KeyWord []string
Where string
}
func main() {
ss := s1{
ID: "123456",
s2: s2{
WebSiteName: "ydook.com",
URL: "www.ydook.com",
},
s3: s3{
// 重点:在结构体内部使用数组
KeyWord: []string{"IT", "AI", "Web", "technology", "knowledge"},
Where: "IT",
},
}
fmt.Println(ss)
}
{
"success": true,
"data": {
"name": "hugo"
},
"identifi": {
"key": "xxx",
"secret": "secret"
},
"errors": [
{
"code": "not_found",
"message": "something"
}
]
}
//
type Resp struct {
Success bool
Identifi struct {
Key string
Secret string
}
Data interface{}
Errors []struct {
Code string
Message string
}
}
resp := new(Resp)
json.Unmarshal(respBody, resp)
- 数组加字典
package main
import (
"fmt"
)
func main() {
result := []map[string]interface{}{}
mp1 := map[string]interface{}{
"one" : 1,"two" : 2,}
mp2 := map[string]interface{}{
"three" : 3,"four" : 4,}
mp3 := make(map[string]interface{})
for k,v := range mp1 {
if _,ok := mp1[k]; ok {
mp3[k] = v
}
}
for k,v := range mp2 {
if _,ok := mp2[k]; ok {
mp3[k] = v
}
}
result = append(result,mp1,mp2)
fmt.Println(result)
}
json性能优化
- 1.使用jsoniter包进行序列化,struct比map更快。
- 2.相对于解码,json.NewEncoder进行大JSON的编码比json.marshal性能高,因为内部使用pool
- 3.json.NewDecoder用于http连接与socket连接的读取与写入,或者文件读取
- 4.json.Unmarshal用于直接是byte的输入
- 5.jsoniter兼容标准库只需要
json := jsoniter.ConfigCompatibleWithStandardLibrary
关键字
go
defer
用于资源的释放,会在函数返回之前,return之后进行调用。
- 特点一:多个defer语句,压入栈后,遵循先入后出规则
- 特点二:defer语句压入时,会将传入的变量值一同压入栈中,不受下文变量值变化的影响
break
跳出当前循环
continue
跳过本次循环,继续下次循环
goto
跳转到指定标签处
时间处理
///时间常量(时间格式化)
const (
ANSIC = "Mon Jan _2 15:04:05 2006"
UnixDate = "Mon Jan _2 15:04:05 MST 2006"
RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
RFC822 = "02 Jan 06 15:04 MST"
RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Kitchen = "3:04PM"
// Handy time stamps.
Stamp = "Jan _2 15:04:05"
StampMilli = "Jan _2 15:04:05.000"
StampMicro = "Jan _2 15:04:05.000000"
StampNano = "Jan _2 15:04:05.000000000"
)
- 时间加减
func main() {
now := time.Now()
m, _ := time.ParseDuration("-1m")
m1 := now.Add(m)
fmt.Println(m1)
fmt.Println(now)
}