golang常用方法积累

golang常用方法积累

  • 日志记录
  • HTTP请求
  • 字符处理
      • strings库
  • 正则匹配
  • 类型定义
    • 不定参数类型定义
    • var
    • const
    • map
      • map转json
    • json
    • type
    • json性能优化
  • 关键字
    • go
    • defer
    • break
    • continue
    • goto
  • 时间处理

日志记录

  • log日志包

学习自:https://www.jianshu.com/p/d634316a9487

func main() {
    log.Println("helloworld:","https://blog.csdn.net/weixin_43819222")
    log.Printf("helloworld:%s\n","https://blog.csdn.net/weixin_43819222")
}
////////////

PrintlnPrintf的区别:
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请求

学习:https://www.cnblogs.com/Paul-watermelon/p/11386392.html

  • 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)
}

https://rabbit52.com/2018/07/go-define-nested-struct/

{
    "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)
}

你可能感兴趣的:(日常积累)