Go Lancet
最后修改时间 2024 年 4 月 11 日
在本文中,我们将展示如何使用 lancet 实用库。
Lancet
Lancet 是一个全面、高效且可重用的 Go 编程语言实用函数库。它包含 600 多个函数。Lancet 涵盖了字符串、切片、日期时间、网络、zip、系统、元组或数据结构等各个领域。
系统功能
在 system 包中,我们提供了一些与系统相关的函数。
package main import ( "fmt" "github.com/duke-git/lancet/v2/system" ) func main() { res := system.GetOsEnv("JAVA_HOME") fmt.Println(res) fmt.Println("----------------------------") stdout, stderr, err := system.ExecCommand("ls") fmt.Println(stdout) fmt.Println(stderr) fmt.Println(err) fmt.Println("----------------------------") if system.IsLinux() { fmt.Println("OS is Linux") } else if system.IsWindows() { fmt.Println("OS is Windows") } else if system.IsMac() { fmt.Println("OS is Mac") } else { fmt.Println("Unknown OS") } }
本示例检索环境变量,运行命令,并确定操作系统。
res := system.GetOsEnv("JAVA_HOME") fmt.Println(res)
使用 GetOsEnv
函数,我们可以检索 JAVA_HOME
目录(如果存在)。
stdout, stderr, err := system.ExecCommand("ls")
我们使用 ExecCommand
运行 ls
命令。
if system.IsLinux() { fmt.Println("OS is Linux") } else if system.IsWindows() { fmt.Println("OS is Windows") } else if system.IsMac() { fmt.Println("OS is Mac") } else { fmt.Println("Unknown OS") }
我们使用 IsLinux
、IsWindows
和 IsMac
函数检查运行的操作系统。
$ go run main.go C:\Users\Jano\.jdks\coretto-17.0.7_7 ---------------------------- Directory: C:\Users\Jano\Documents\prog\go\lancet\system Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 23. 9. 2023 15:26 167 go.mod -a---- 23. 9. 2023 15:26 2941 go.sum -a---- 23. 9. 2023 15:27 596 main.go <nil> ------------------ OS is Windows
元组函数
Lancet 支持元组。
package main import ( "fmt" "github.com/duke-git/lancet/v2/tuple" ) func main() { t := tuple.NewTuple2(1, 0.1) x, y := t.Unbox() fmt.Println(x) fmt.Println(y) fmt.Printf("%v %v", t.FieldA, t.FieldB) t2 := tuple.NewTuple3(1, 0.1, "a") fmt.Printf("%v %v %v", t2.FieldA, t2.FieldB, t2.FieldC) a, b, c := t2.Unbox() fmt.Println(a) fmt.Println(b) fmt.Println(c) }
本示例定义并解包了两个元素和三个元素的元组。
$ go run main.go 1 0.1 1 0.11 0.1 a1 0.1 a
日期和时间函数
在 datetime
包中,我们提供了一些与日期和时间相关的函数。
package main import ( "fmt" "time" "github.com/duke-git/lancet/v2/datetime" ) func main() { now := time.Now() dt := datetime.AddYear(now, 11) fmt.Println(dt) fmt.Println(datetime.FormatTimeToStr(dt, "yyyy-mm-dd")) res2 := datetime.EndOfYear(now) fmt.Println(res2) begin := datetime.BeginOfWeek(now) fmt.Println(begin) }
本示例展示了 AddYear
、FormatTimeToStr
、EndOfYear
和 BeginOfWeek
函数。
$ go run main.go 2034-09-20 15:45:35.7624076 +0200 CEST m=+346896000.002289001 2034-09-20 2023-12-31 23:59:59.999999999 +0100 CET 2023-09-17 00:00:00 +0200 CEST
切片函数
在下一个示例中,我们将展示一些切片函数。
package main import ( "fmt" "github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/v2/strutil" ) func main() { vals := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} isEven := func(i, num int) bool { return num%2 == 0 } n1 := slice.CountBy(vals, isEven) fmt.Println(n1) words := []string{"sky", "war", "blue", "war", "cottage", "war", "car", "pen", "book"} n2 := slice.Count(words, "war") fmt.Println(n2) fmt.Println("------------------------------") shuffled := slice.Shuffle(vals) slice.ForEach(shuffled, func(_, e int) { fmt.Println(e) }) fmt.Println("------------------------------") res := slice.Map(vals, func(_, e int) int { return e * 2 }) fmt.Println(res) res2 := slice.Map(words, func(_ int, e string) string { return strutil.UpperFirst(e) }) fmt.Println(res2) }
本示例使用了 CountBy
、Count
、Shuffle
、Map
和 ForEach
切片函数。
vals := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} isEven := func(i, num int) bool { return num%2 == 0 } n1 := slice.CountBy(vals, isEven)
使用 CountBy
,我们计算 isEven
predicate 返回 true 的切片元素的数量。
words := []string{"sky", "war", "blue", "war", "cottage", "war", "car", "pen", "book"} n2 := slice.Count(words, "war")
我们计算 words
切片中 war
单词的出现次数。
shuffled := slice.Shuffle(vals) slice.ForEach(shuffled, func(_, e int) { fmt.Println(e) })
我们使用 Shuffle
随机排列 vals
切片,并使用 ForEach
遍历它。
res := slice.Map(vals, func(_, e int) int { return e * 2 }) fmt.Println(res)
使用 Map
,我们将给定的匿名函数应用于切片中的每个元素。
$ go run main.go 5 3 ------------------------------ 6 10 11 9 7 2 1 5 3 4 8 ------------------------------ [12 20 22 18 14 4 2 10 6 8 16] [Sky War Blue War Cottage War Car Pen Book]
网络函数
我们提供了一些网络相关的函数。
package main import ( "fmt" "log" "github.com/duke-git/lancet/v2/netutil" ) type Post struct { UserId int `json:"userId"` Id int `json:"id"` Title string `json:"title"` Body string `json:"body"` } func main() { req := &netutil.HttpRequest{ RawURL: "https://jsonplaceholder.typicode.com/posts/1", Method: "GET", } client := netutil.NewHttpClient() resp, err := client.SendRequest(req) if err != nil || resp.StatusCode != 200 { log.Fatal(err) } var body Post err = client.DecodeResponse(resp, &body) if err != nil { log.Fatal(err) } fmt.Println(body) fmt.Println("-------------------------") fmt.Println(body.Id) fmt.Println(body.UserId) fmt.Println(body.Title) fmt.Println(body.Body) }
本示例从在线测试服务检索一个帖子。
req := &netutil.HttpRequest{ RawURL: "https://jsonplaceholder.typicode.com/posts/1", Method: "GET", }
我们定义了一个 HTTP GET 请求。
client := netutil.NewHttpClient() resp, err := client.SendRequest(req)
创建了一个 HTTP 客户端并发送了一个新请求。
if err != nil || resp.StatusCode != 200 { log.Fatal(err) }
我们检查响应状态和错误。
var body Post err = client.DecodeResponse(resp, &body) if err != nil { log.Fatal(err) }
我们将 JSON 响应解码到 Post 结构体正文中。
排序函数
algorithm
包包含一些排序算法。
在下一个示例中,我们使用快速排序算法。
package main import ( "fmt" "github.com/duke-git/lancet/v2/algorithm" ) type intComparator struct{} func (c *intComparator) Compare(e1 any, e2 any) int { val1, _ := e1.(int) val2, _ := e2.(int) if val1 < val2 { return -1 } else if val1 > val2 { return 1 } return 0 } func main() { vals := []int{2, 1, 5, 3, 6, 4, -2, 0, 9, 11, -3} comparator := &intComparator{} algorithm.QuickSort(vals, comparator) fmt.Println(vals) }
本示例使用快速排序算法对切片中的整数进行排序。
type intComparator struct{} func (c *intComparator) Compare(e1 any, e2 any) int { val1, _ := e1.(int) val2, _ := e2.(int) if val1 < val2 { return -1 } else if val1 > val2 { return 1 } return 0 }
我们定义了 Compare
函数。
comparator := &intComparator{} algorithm.QuickSort(vals, comparator)
我们使用 QuickSort
对数字进行排序。
$ go run main.go [-3 -2 0 1 2 3 4 5 6 9 11]
下面的示例使用插入排序算法。
package main import ( "fmt" "github.com/duke-git/lancet/v2/algorithm" ) type User struct { Name string Age int } type byAge struct{} func (c *byAge) Compare(u1 any, u2 any) int { p1, _ := u1.(User) p2, _ := u2.(User) if p1.Age < p2.Age { return -1 } else if p1.Age > p2.Age { return 1 } return 0 } func main() { users := []User{ {Name: "Peter", Age: 20}, {Name: "Julia", Age: 14}, {Name: "Lucia", Age: 17}, {Name: "Roman", Age: 18}, {Name: "Jan", Age: 28}, } comparator := &byAge{} algorithm.InsertionSort(users, comparator) fmt.Println(users) }
本示例使用 InsertionSort
按年龄对用户进行排序。
func (pc *byAge) Compare(u1 any, u2 any) int { p1, _ := u1.(User) p2, _ := u2.(User) if p1.Age < p2.Age { return -1 } else if p1.Age > p2.Age { return 1 } return 0 }
我们定义了 Compare
函数。
comparator := &byAge{} algorithm.InsertionSort(users, comparator)
我们使用 InsertionSort
对用户进行就地排序。
$ go run main.go [{Julia 14} {Lucia 17} {Roman 18} {Peter 20} {Jan 28}]
字符串函数
字符串函数位于 strutil
包中。
package main import ( "fmt" "github.com/duke-git/lancet/v2/strutil" ) func main() { msg := "an old falcon" fmt.Println(strutil.CamelCase(msg)) fmt.Println(strutil.Capitalize(msg)) fmt.Println(strutil.KebabCase(msg)) fmt.Println(strutil.UpperFirst(msg)) fmt.Println(strutil.SnakeCase(msg)) fmt.Println(strutil.Reverse(msg)) }
本示例使用六个不同的函数修改一个字符串。
$ go run main.go anOldFalcon An old falcon an-old-falcon An old falcon an_old_falcon noclaf dlo na
接下来我们使用另外 4 个函数。
package main import ( "fmt" "github.com/duke-git/lancet/v2/strutil" ) func main() { msg := "F# мультипарадигмальный язык программирования из семейства языков .NET." fmt.Println(strutil.WordCount(msg)) fmt.Println(strutil.IsString(msg)) w1 := "\t" w2 := " " w3 := "." fmt.Println(strutil.IsBlank(w1)) fmt.Println(strutil.IsBlank(w2)) fmt.Println(strutil.IsBlank(w3)) fmt.Println(strutil.IsBlank(strutil.Trim(w1))) }
在下一个示例中,我们计算字符串中的单词数,并使用 IsString
和 IsBlank
检查值,并使用 Trim
修剪字符串。
$ go run main.go 8 true true true false true
Function 包
function
包可以控制函数执行流程,并为函数式编程提供一些支持。
package main import ( "fmt" "github.com/duke-git/lancet/v2/function" "github.com/duke-git/lancet/v2/slice" ) func double(vals []int) []int { return slice.Map(vals, func(_, e int) int { return e * 2 }) } func incByOne(vals []int) []int { return slice.Map(vals, func(_, e int) int { return e + 1 }) } func main() { vals := []int{1, 2, 3, 4, 5} transform := function.Pipeline(double, incByOne) res := transform(vals) fmt.Println(res) }
在本示例中,我们调用 Pipeline
将两个函数管道化到 vals
切片上。
func double(vals []int) []int { return slice.Map(vals, func(_, e int) int { return e * 2 }) } func incByOne(vals []int) []int { return slice.Map(vals, func(_, e int) int { return e + 1 }) }
我们有两个函数,它们将切片元素加倍并递增。
transform := function.Pipeline(double, incByOne)
我们创建了一个由这两个函数组成的管道。
res := transform(vals)
管道被执行。
$ go run main.go [3 5 7 9 11]
Zip
fileutil
包包含一个 Zip
函数,用于创建 ZIP 存档。
package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { err := fileutil.Zip(".", "current.zip") if err != nil { fmt.Println(err) } }
本示例从当前工作目录创建了一个 ZIP 存档。
来源
在本文中,我们使用了 lancet 实用库。