go技巧分享(三)

这是一个系列文章,主要分享go的使用建议和技巧,每次分享3点,希望你能有所收获。

1 打印更易读的结构体

package main

import "fmt"

type User struct {
    Name string
    Age  int
    Addr string
}

func main() {
    u := User{"user1", 12, "addr"}
    fmt.Printf("%v\n", u)
    fmt.Printf("%+v\n", u)
    fmt.Printf("%#v\n", u)
}

/*
{user1 12 addr}
{Name:user1 Age:12 Addr:addr}
main.User{Name:"user1", Age:12, Addr:"addr"}
*/

由示例中可以看到,这里定义了一个叫User的结构体,结构体中有Name、Age和Addr三个字段,第一种打印方式通过%v,只能看到结构体的字段值,如果字段较多,可读性不是很好。第二种打印方式通过%+v,会打印出结构体的每个字段名和相应字段的值。第三种打印方式通过%#v,会打印出结构体的具体类型、字段名称和字段值,方便检查结构的详细信息。所以如果需要在日志中打印具体的结构体信息,可以使用%#v方式。

2 简易定时器实现

package main

import (
    "fmt"
    "time"
)

func main() {
    for range time.Tick(3 * time.Second) {
        fmt.Println(time.Now().Format(time.ANSIC))
    }
}
$ go run timer_demo.go
Mon May 20 14:43:47 2018
Mon May 20 14:43:50 2018
Mon May 20 14:43:53 2018
(省略)

通过使用time包中的Tick函数,可以实现一个简单的定时器,配合for循环可以周期性的执行某些操作。由示例中可以看到,执行示例程序,每隔3s会打印当前的系统时间。

3 正确的字符串连接方式

package main

import (
    "bytes"
    "fmt"
    "time"
)

func main() {
    totalStrs := 100000
    strList := make([]string, 0, totalStrs)
    for i := 0; i < totalStrs; i++ {
        strList = append(strList, fmt.Sprintf("string %d", i))
    }

    joinStrByAdd(strList)
    joinStrByBuffer(strList)
}

func joinStrByAdd(strList []string) string {
    defer Elapsed(time.Now(), "joinStrByAdd")
    joinStr := ""
    for _, str := range strList {
        joinStr += str
    }
    return joinStr
}

func joinStrByBuffer(strList []string) string {
    defer Elapsed(time.Now(), "joinStrByBuffer")
    var joinStr bytes.Buffer
    for _, str := range strList {
        joinStr.WriteString(str)
    }
    return joinStr.String()
}

func Elapsed(start time.Time, funcName string) {
    fmt.Printf("call %s took %f seconds\n", funcName, time.Since(start).Seconds())
}

/*
call joinStrByAdd took 24.579838 seconds
call joinStrByBuffer took 0.002363 seconds
*/

通过bytes.Buffer的缓存机制,在连接大量字符串时,可以大大的提升性能。由示例中可以看到,这里模拟了10万个字符串连接操作,使用传统的加号方式和使用bytes.Buffer方式,性能相差上万倍。其实不止go语言提供了这种缓存机制,大多数语言都有类似方式实现字符串连接。

LEo at 00:05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android 开发学习

JsBridge 源码分析

1733
来自专栏大内老A

WCF的Binding模型之四:信道工厂(Channel Factory)

由于信道管理器在客户端和服务端所起的不同作用,分为信道监听器和信道工厂。和服务端的信道监听其相比,处于客户端的信道工厂显得简单。从名称就可以看得出来,信道工厂的...

1818
来自专栏恰童鞋骚年

ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程

开篇:上一篇我们了解了在WebForm模式下一个Page页面的生命周期,它经历了初始化Init、加载Load以及呈现Render三个重要阶段,其中构造了页面控件...

1393
来自专栏XAI

微信公众号发送模板消息 Java实现。

本博文是测试公众号调用模板接口测试。请不要完全复制我的代码。里面的测试代码中有本人测试号的微信模板id。麻烦替换成自己的可以吗? 第一步:创建模板信息 ? ? ...

1K11
来自专栏个人分享

初版storm项目全流程自动化测试代码实现

  由于项目需要,写了版针对业务的自动化测试代码,主要应用场景在于由于业务日趋复杂,一些公共代码的改动,担心会影响已有业务。还没进行重写,但知识点还是不少的与大...

891
来自专栏進无尽的文章

编码篇-学会小用宏和条件编译

宏定义在C系开发中可以说占有举足轻重的作用。底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步难行。而在更...

1641
来自专栏chenssy

【追光者系列】HikariCP源码分析之evict、时钟回拨、连接创建生命周期

evict定义在com.zaxxer.hikari.pool.PoolEntry中,evict的汉语意思是驱逐、逐出,用来标记连接池中的连接不可用。

3814
来自专栏Thomas的技术专栏

Ffmpeg对sps/pps的解析和格式转换

H264流的 SPS(序列参数集Sequence Parameter Set)和PPS(图像参数集Picture Parameter Set)记录了视频的基本编...

1.1K2
来自专栏java一日一条

50个常见的 Java 错误及避免方法(第三部分)

当我们尝试调用带有错误参数的Java代码时,通常会产生此Java错误消息(@ghacksnews):

1473
来自专栏流柯技术学院

python批量下载图片的三种方法

win32com可以获得类似js里面的document对象,但貌似是只读的(文档都没找到)。

2112

扫码关注云+社区

领取腾讯云代金券