美文网首页读书谈技术
我几乎在每个项目中使用的 5 个 Go 库

我几乎在每个项目中使用的 5 个 Go 库

作者: 技术的游戏 | 来源:发表于2023-05-11 23:03 被阅读0次

    我注意到这些库似乎总是我在开始一个新项目时首先接触到的库。它们已成为我快速启动和运行的首选工具。

    在Go语言中,库就像是一个宝库,里面有许多有价值的资源可以帮助开发人员创建更好、更快的应用程序。

    我很幸运能够在我的职业生涯中尝试了大量的库,可以证明选择正确的库确实可以彻底改变游戏规则,消除冗余代码,并提高我的服务的整体质量。

    1. golang-module/carbon

    在Go中使用时间可以是一个挑战,特别是当仅依赖内置的time.Time包时,例如。

    您如何在Go中指定时间的年份或月份?

    过去,当我尝试操作时间值时,经常会遇到复杂的代码。

    t := time.Now() // get the current time
    
    // change the year to 2020
    newTime := time.Date(2020, t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second
    

    这正是Carbon的用武之地,它提供了一种优雅高效的解决方案,只需一行简短的代码即可实现。

    t := carbon.Now().SetYear(2020)
    

    “就这么简单?”

    Carbon提供了许多有用的工具,使在Go中使用时间变得更加可管理,避免了直接处理time.Time对象时的烦恼和麻烦。

    为了让您了解carbon在实践中的工作方式,这里有一些我从他们的GitHub文档中摘录的例子,我认为您会觉得很有帮助。

    // Whether is now time
    carbon.Now().IsNow() // true
    // Whether is future time
    carbon.Tomorrow().IsFuture() // true
    // Whether is pass time
    carbon.Yesterday().IsPast() // true
    
    // Whether is January
    carbon.Parse("2020-08-05 13:14:15").IsJanuary() // false
    // Whether is Monday
    carbon.Parse("2020-08-05 13:14:15").IsMonday() // false
    
    carbon.Parse("2020-08-05 13:14:15").DiffForHumans() // just now
    carbon.Parse("2022-08-05 13:14:15").DiffForHumans() // 2 years from now
    

    2. samber/lo

    如果你在Go项目中经常使用切片、数组或集合,那么你可能想要尝试一下Samber/lo库。

    该库受到Lodash的启发,使用新的Go 1.18+泛型特性构建,提供了一系列有用的实用程序,如过滤器、集合、归约、计数和展平,以简化复杂的任务并使你的代码更加高效。

    例如,你可以使用Samber/lo库通过其实用程序以Go风格重写Python的range函数。

    result := lo.Range(4)
    // [0, 1, 2, 3]
    
    result := lo.RangeFrom(1, 5)
    // [1, 2, 3, 4, 5]
    

    和前面的部分一样,我将提供一些取自他们GitHub文档的示例,以便让你更好地了解Samber/lo的功能。

    // Find unique values
    names := lo.Uniq[string]([]string{"Samuel", "John", "Samuel"})
    // []string{"Samuel", "John"}
    
    // Filter even number
    even := lo.Filter[int]([]int{1, 2, 3, 4}, func(x int, index int) bool {
        return x%2 == 0
    })
    // []int{2, 4}
    
    // Reverse the slice
    reverseOrder := lo.Reverse[int]([]int{0, 1, 2, 3, 4, 5})
    // []int{5, 4, 3, 2, 1, 0}
    

    Samber/lo 不仅提供了处理切片、数组和集合的实用程序,还包括一些我经常使用的便捷函数。

    例如,它提供了一个函数用于生成随机字符串,另一个函数用于检查结构体是否已初始化。

    // ---- RandomString
    str := lo.RandomString(5, lo.LettersCharset)
    // "eIGbt"
    
    // ---- IsNotEmpty
    type test struct {
      foorbar string
    }
    
    lo.IsNotEmpty[test](test{foobar: ""})
    // false
    lo.IsNotEmpty[test](test{foobar: "foobar"})
    // true
    

    3. zerolog

    在开发大型项目时,将日志进行结构化以提高可读性、可查询性和速度是非常重要的。

    “为什么你选择不使用其他结构化日志库,如logrus或zap?”

    Zerolog 是一款高性能且极易使用的日志库。我的一个重要规则是:“如果你被众多不同的选项所淹没,不要浪费时间,随意选择一个并通过试错实验开始尝试。”

    除了其卓越的性能外,Zerolog 还提供了许多有用的工具。

    例如,您可以使用 Zerolog 记录日志事件被发出的位置,以便于跟踪代码中的错误和问题。

    log.Logger = log.With().Caller().Logger()
    log.Info().Msg("hello world")
    
    // Output: {"level": "info", "message": "hello world", 
    // "caller": "/go/src/your_project/some_file:21"}
    

    4. jinzhu/copier

    关于复制或深度克隆,Copier是一个很方便的工具。

    当处理复杂的数据结构或嵌套结构时,手动复制数据可能会是一个繁琐且容易出错的任务。 Copier 在这种情况下非常有用。

    copier.CopyWithOption(&to, &from, copier.Option{IgnoreEmpty: true, DeepCopy: true})
    

    举个例子,假设我们有两个模型:User,包含用户的所有信息,以及SimpleUser,不包括他们的电子邮件和密码。

    type User struct {
      Name string 
      Age int 
      Email string 
      Password string
    }
    
    type SimpleUser struct {
      Name string 
      Age int
    }
    

    假设我需要从数据库中检索用户信息,处理它,并返回经修改的用户对象的版本,该版本不包含敏感信息,例如电子邮件和密码,以避免任何安全漏洞。

    // --- Mockup
    func getUserFromDB() User {
      return User{
        Name: "Aiden", Age: 30,
        Email: "aidenlee@gmail.com", Password: "thisisasecret"}
    }
    
    // --- 
    func Sample() (s SimpleUser, err error) {
     user := getUserFromDB()
    
     // ... doing thing with user then return simpleUser
    
     err = copier.Copy(&s, &user);
     return s, err
    }
    

    当需要创建结构体的深层副本时,Copier 是一个非常方便的工具(但可能无法处理非公开字段)。

    func Clone[T any](input T) (*T, error) {
      var output = new(T)
      err := copier.CopyWithOption(output, input, copier.Option{DeepCopy: true})
      return output, err 
    }
    

    Copier提供了一系列功能。

    • 从相同名称的字段复制到字段
    • 从具有相同名称的方法复制到字段
    • 从字段复制到具有相同名称的方法
    • 从一个切片复制到另一个切片
    • 从结构体复制到切片
    • 从集合复制到集合
    • 强制复制带有标记的字段
    • 忽略带有标记的字段
    • 深度复制

    5. stretchr/testify

    在其他语言(如C#,带有Selenium或Playwright的Javascript)中处理测试时,你可能熟悉使用断言和期望。但是,在Go中,我找不到类似的东西,直到我发现了testify包。

    Testify的assert包为我们的测试提供了各种有用的工具,例如。

    func TestSomething(t *testing.T) {
    
      // assert equality
      assert.Equal(t, 123, 123, "they should be equal")
    
      // assert inequality
      assert.NotEqual(t, 123, 456, "they should not be equal")
    
      // assert for nil (good for errors)
      assert.Nil(t, object)
    
      // assert for not nil (good when you expect something)
      if assert.NotNil(t, object) {
    
        // now we know that object isn't nil, we are safe to make
        // further assertions without causing any errors
        assert.Equal(t, "Something", object.Value)
    
      }
    }
    

    在 testify v1 中(在我撰写本文时,Testify 团队正在开发 v2),该库提供了几个功能来方便 Go 语言中的测试:

    • Asserts 包,我们已经提到过。
    • Mock 包:提供了一种简单的方法来创建可以在测试期间替换实际对象的模拟对象。
    • Suite 包:您可以使用结构体构建测试套件,在结构体上定义设置/拆卸和测试方法,并像平常一样使用 'go test' 运行它们。

    这里只是我在使用 Go 语言开发项目时发现非常有用的一些库。永远记住发挥自己的生产力,愉快编码 :)

    每日列表

    2,000 名软件开发人员会收到我的每日文章,直接发送到他们的订阅消息中。

    如果你喜欢我的文章,点赞,关注,转发!

    相关文章

      网友评论

        本文标题:我几乎在每个项目中使用的 5 个 Go 库

        本文链接:https://www.haomeiwen.com/subject/ihijsdtx.html