前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言Tips

Go语言Tips

作者头像
张子阳
发布2018-09-30 10:00:57
9200
发布2018-09-30 10:00:57
举报

Go语言Tips

2017-12-13 作者: 张子阳 分类: Go 语言

转型到Go以后,因为语言的不熟悉,以往很常见的一些操作有时候也需要去Google一下。这里将一些结果记录下来,方便日后查阅。

这篇文章没有什么讲解,都是一些小例子,有点类似于:go by example

如何解析XML?

我没有找到类似C#中的xml API可以动态地解析xml结构, 或者通过XPath来对xml结构进行搜索。只能一次性映射成一个struct,然后通过struct的属性去访问,这样每次解析都要构建一个对应的struct,稍显麻烦,可能有更好的解决方案,只是我不知道吧。

好处是,即使xml和struct并不完全对应,也可以正确解析,否则就会变得无比麻烦。

代码语言:txt
复制
// Root 根节点
type Root struct {
    XMLName    xml.Name `xml:"xml"`
    ReturnCode string   `xml:"return_code"`
    ReturnMsg  string   `xml:"return_msg"`
    ResultCode string   `xml:"result_code"`
    ErrCode    string   `xml:"err_code"`
    ErrCodeDes string   `xml:"err_code_des"`
    CodeURL    string   `xml:"code_url"`
}

func testXML() {
    xmlStr := `<xml>
    <return_code><![CDATA[SUCCESS]]></return_code>
    <return_msg><![CDATA[OK]]></return_msg>
    <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
    <mch_id><![CDATA[10000100]]></mch_id>
    <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
    <openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid>
    <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
    <result_code><![CDATA[SUCCESS]]></result_code>
    <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
    <trade_type><![CDATA[Native]]></trade_type>
    <code_url><![CDATA[weixin://wxpay/s/An4baqw]]></code_url>
 </xml>`

    xmlByte := []byte(xmlStr)
    var root Root
    xml.Unmarshal(xmlByte, &root)
    fmt.Println(root.ReturnCode)
    fmt.Println(root.CodeURL)
    fmt.Println("root.ErrCode", root.ErrCode) // 这个是没有的
}

如何将各种类型转换成字符串?

Go的字符串类型转换有时候真的是让萌新有点犯晕。

代码语言:txt
复制
func convertToString() {
    var text string

    // int 转换成字符串
    text = strconv.Itoa(10000)
    fmt.Println("text:", text)

    // interface{} 转换成字符串
    var i interface{}
    i = "hello"
    text = i.(string)
    fmt.Println("text:", text)

    // byte[] 转换成字符串
    data := []byte("world")
    text = string(data)
    fmt.Println("text:", text)
}   

如何生成随机数?如何用某一字符补齐特定长度字符串?

这个小小的以日期+随机数作为唯一编号的函数包含了这两个功能。

代码语言:txt
复制
func GetDateNo() string {
    // 生成随机数:0~9999
    src := rand.NewSource(time.Now().UnixNano())
    r := rand.New(src)
    suffix := strconv.Itoa(r.Intn(10000))

    // 最大长度为4,并且用0来补齐
    if len(suffix) < 4 {
        suffix = fmt.Sprintf("%04s", suffix)
    }

    str := time.Now().Format("060102150405") + suffix
    return str
}

如何对map按照key进行排序?

无法对map进行排序,如果需要按顺序处理map,可以用下面的方法间接进行。

代码语言:txt
复制
// 对map进行排序
func sortMap(dic map[string]string) {
    var keys []string

    for k := range dic {
        keys = append(keys, k)
    }
    sort.Strings(keys)

    for _, k := range keys {
        // 在这里进行处理
        fmt.Println(k, ":", dic[k])
    }
}

如何生成Md5加密字符串?

代码语言:txt
复制
// GetMd5 获得md5字符串
func GetMd5(text string) string {
    data := []byte(text)
    cryptoData := md5.Sum(data)
    cryptoText := hex.EncodeToString(cryptoData[:])
    return cryptoText
}

如何获取当前程序的运行目录?

代码语言:txt
复制
func main() {
    dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Path:", dir) 
}

如何获取当前的GOPATH路径?

代码语言:txt
复制
func main(){
    fmt.Println(build.Default.GOPATH)
}

如何发起HttpGet请求,并以字符串返回结果?

代码语言:txt
复制
// HTTPGet 发起HttpGet请求,并返回string格式的结果
func HTTPGet(url string) (string, error) {
    res, err := http.Get(url)

    if err != nil {
        log.Error(err.Error(), "HTTPGet")
        return "", err
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Error(err.Error(), "HTTPGet")
        return "", err
    }

    return string(body), nil
}

如何发起HttpPost请求,并以字符串返回结果?

代码语言:txt
复制
// HTTPPost 发起http post请求
func HTTPPost(url string, body string) (string, error) {
    data := []byte(body)
    reader := bytes.NewReader(data)

    res, err := http.Post(url, "application/x-www-form-urlencoded", reader)

    if err != nil {
        log.Error(err.Error(), "HTTPPost-1")
        return "", err
    }

    resBody, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Error(err.Error(), "HTTPPost-2")
        return "", err
    }

    return string(resBody), nil
}

如何生成QR二维码

首先 go get github.com/boombuler/barcode,然后看下面范例。

代码语言:txt
复制
package main

import (
    "bytes"
    "fmt"
    "image/png"
    "os"

    "github.com/boombuler/barcode"
    "github.com/boombuler/barcode/qr"
)

生成QR图片

代码语言:txt
复制
func createQRImage() {
    qrCode, _ := qr.Encode("http://www.baidu.com", qr.M, qr.Auto)
    qrCode, _ = barcode.Scale(qrCode, 200, 200)

    file, _ := os.Create("qrcode.png")
    defer file.Close()

    png.Encode(file, qrCode)
}

生成QR byte数组(应该更常用一些,可以直接http返回)

代码语言:txt
复制
func createQRByte() []byte {
    qrCode, _ := qr.Encode("http://www.baidu.com", qr.M, qr.Auto)
    qrCode, _ = barcode.Scale(qrCode, 200, 200)

    buf := new(bytes.Buffer)
    png.Encode(buf, qrCode)

    bytes := buf.Bytes()
    return bytes
}

如何正确转换日期?

因为我们的时区是UTC+8,所以关于时间,如果不小心处理就会出现相差8小时的错误。看下面的代码:

代码语言:txt
复制
func main() {
    const LayOut = "2006-01-02 15:04:05"

    // 获取当前日期并转换为字符串打印
    now := time.Now()
    nowStr := now.Format(LayOut)
    fmt.Println(nowStr)

    // 将字符串转换为日期,再转换回去然后打印
    now2, _ := time.Parse(LayOut, nowStr)
    now2Str := now2.Format(LayOut)
    fmt.Println(now2Str)

    diff := now.Sub(now2)
    fmt.Println("total :", diff.Hours())
}

按正常理解,这样转换后的结果应该是完全一致的,结果实际上now比now2早了8小时。

代码语言:txt
复制
2017-12-14 14:53:00
2017-12-14 14:53:00
total : -7.999736999166666

字符串的值完全相等,但是diff一下发现实际不一样。其实将上面的例子稍微修改一下,就知道差别了:

代码语言:txt
复制
// 相同代码省略
fmt.Println(now.String())
fmt.Println(now2.String())

输出为:

代码语言:txt
复制
2017-12-14 15:05:12.3921453 +0800 CST
2017-12-14 15:05:12 +0000 UTC
total : -7.99989107075

可以看到两个时间是不一样的,所以在从字符串转换为日期的时候,需要将当前时区传进去,这里是正确版本:

代码语言:txt
复制
Beijing, _ := time.LoadLocation("Asia/Shanghai")
now2, _ := time.ParseInLocation(LayOut, nowStr, Beijing)
fmt.Println(now2.String())

如何获取当前URL?

本想通过url.URL获取当前URL全路径,结果本地(localhost)测试时,scheme为空,host为空,所以通过http.Request来获得,结果scheme还是空。没有啥其他办法,暂时写死了。

代码语言:txt
复制
func getFullURL(r *http.Request) string {    
    
    return "http://" + r.Host + r.RequestURI
    // return r.URL.Scheme + "://" + r.Host + r.RequestURI
}

感谢阅读,希望这篇文章能给你带来帮助!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Go语言Tips
    • 如何解析XML?
      • 如何将各种类型转换成字符串?
        • 如何生成随机数?如何用某一字符补齐特定长度字符串?
          • 如何对map按照key进行排序?
            • 如何生成Md5加密字符串?
              • 如何获取当前程序的运行目录?
                • 如何获取当前的GOPATH路径?
                  • 如何发起HttpGet请求,并以字符串返回结果?
                    • 如何发起HttpPost请求,并以字符串返回结果?
                      • 如何生成QR二维码
                        • 如何正确转换日期?
                          • 如何获取当前URL?
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档