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 实用库。