docs: 优化文档展示,适配部分无目录文档,适配非结构体的类型定义,增加测试用例文档

This commit is contained in:
kercylan
2024-01-14 18:32:44 +08:00
parent 83beeb43ce
commit b2fdaa2ae6
80 changed files with 9523 additions and 1473 deletions

View File

@@ -1,5 +1,8 @@
# Utils
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/utils)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
utils 旨在提供一组用于处理通用功能的函数和数据结构。该包旨在简化通用功能的实现,并提供一致的接口和易于使用的功能。
主要特性:
- 通用功能utils 包支持处理各种通用功能,如字符串处理、日期时间操作和文件操作等。您可以使用这些功能来解决各种通用问题,并提高代码的复用性和可维护性。
@@ -7,26 +10,6 @@ utils 旨在提供一组用于处理通用功能的函数和数据结构。该
- 算法实现utils 包还提供了一些常用的算法实现,如排序算法、搜索算法和图算法等。这些算法可以用于解决各种问题,并提供高效的计算和处理能力。
- 工具函数:该包还提供了一些通用的工具函数,如字符串处理、日期时间操作和文件操作等。这些工具函数可以帮助您简化代码编写,处理文本数据,操作日期时间,读写文件等。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/utils)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
> 包级函数定义
|函数|描述
|:--|:--
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息

View File

@@ -1,5 +1,8 @@
# Aoi
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/aoi)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
aoi 提供了一种有效的方法来处理 AOIArea of Interest问题。
AOI 问题是在大规模多人在线游戏中常见的问题,它涉及到确定哪些对象对玩家来说是“感兴趣的”,
@@ -7,37 +10,62 @@ AOI 问题是在大规模多人在线游戏中常见的问题,它涉及到确
这个包提供了一种数据结构和一些方法来有效地解决这个问题。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/aoi)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewTwoDimensional](#NewTwoDimensional)|暂无描述...
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[TwoDimensional](#twodimensional)|暂无描述...
|[TwoDimensionalEntity](#twodimensionalentity)|基于2D定义的AOI对象功能接口
|[EntityJoinVisionEventHandle](#entityjoinvisioneventhandle)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[TwoDimensional](#twodimensional)|暂无描述...
|`INTERFACE`|[TwoDimensionalEntity](#twodimensionalentity)|基于2D定义的AOI对象功能接口
|`STRUCT`|[EntityJoinVisionEventHandle](#entityjoinvisioneventhandle)|暂无描述...
</details>
***
## 详情信息
#### func NewTwoDimensional(width int, height int, areaWidth int, areaHeight int) *TwoDimensional[EID, PosType, E]
<span id="NewTwoDimensional"></span>
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewTwoDimensional(t *testing.T) {
aoiTW := aoi.NewTwoDimensional[int64, float64, *Ent](10000, 10000, 100, 100)
start := time.Now()
for i := 0; i < 50000; i++ {
aoiTW.AddEntity(&Ent{guid: int64(i), pos: geometry.NewPoint[float64](float64(random.Int64(0, 10000)), float64(random.Int64(0, 10000))), vision: 200})
}
fmt.Println("添加耗时:", time.Since(start))
start = time.Now()
aoiTW.SetSize(10100, 10100)
fmt.Println("重设大小耗时:", time.Since(start))
}
```
</details>
***
### TwoDimensional
### TwoDimensional `STRUCT`
```go
type TwoDimensional[EID generic.Basic, PosType generic.SignedNumber, E TwoDimensionalEntity[EID, PosType]] struct {
@@ -54,14 +82,18 @@ type TwoDimensional[EID generic.Basic, PosType generic.SignedNumber, E TwoDimens
repartitionQueue []func()
}
```
### TwoDimensionalEntity
### TwoDimensionalEntity `INTERFACE`
基于2D定义的AOI对象功能接口
- AOI 对象提供了 AOI 系统中常用的属性,诸如位置坐标和视野范围等
```go
type TwoDimensionalEntity[EID generic.Basic, PosType generic.SignedNumber] struct{}
type TwoDimensionalEntity[EID generic.Basic, PosType generic.SignedNumber] interface {
GetTwoDimensionalEntityID() EID
GetVision() float64
GetPosition() geometry.Point[PosType]
}
```
### EntityJoinVisionEventHandle
### EntityJoinVisionEventHandle `STRUCT`
```go
type EntityJoinVisionEventHandle[EID generic.Basic, PosType generic.SignedNumber, E TwoDimensionalEntity[EID, PosType]] struct{}
type EntityJoinVisionEventHandle[EID generic.Basic, PosType generic.SignedNumber, E TwoDimensionalEntity[EID, PosType]] func(entity E)
```

View File

@@ -1,21 +1,22 @@
# Arrangement
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/arrangement)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
arrangement 包提供了一些有用的函数来处理数组的排列。
更多的详细信息和使用示例,可以参考每个函数的文档。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/arrangement)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[WithAreaConstraint](#WithAreaConstraint)|设置编排区域的约束条件
|[WithAreaConflict](#WithAreaConflict)|设置编排区域的冲突条件,冲突处理函数需要返回造成冲突的成员列表
@@ -29,62 +30,72 @@ arrangement 包提供了一些有用的函数来处理数组的排列。
|[WithConflictHandle](#WithConflictHandle)|设置编排时触发冲突时的处理函数
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Area](#area)|编排区域
|[AreaOption](#areaoption)|编排区域选项
|[AreaConstraintHandle](#areaconstrainthandle)|暂无描述...
|[Arrangement](#arrangement)|用于针对多条数据进行合理编排的数据结构
|[Editor](#editor)|提供了大量辅助函数的编辑器
|[Item](#item)|编排成员
|[ItemOption](#itemoption)|编排成员选项
|[ItemFixedAreaHandle](#itemfixedareahandle)|暂无描述...
|[Option](#option)|编排选项
|[ConstraintHandle](#constrainthandle)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Area](#area)|编排区域
|`STRUCT`|[AreaOption](#areaoption)|编排区域选项
|`STRUCT`|[AreaConstraintHandle](#areaconstrainthandle)|暂无描述...
|`STRUCT`|[Arrangement](#arrangement)|用于针对多条数据进行合理编排的数据结构
|`STRUCT`|[Editor](#editor)|提供了大量辅助函数的编辑器
|`INTERFACE`|[Item](#item)|编排成员
|`STRUCT`|[ItemOption](#itemoption)|编排成员选项
|`STRUCT`|[ItemFixedAreaHandle](#itemfixedareahandle)|暂无描述...
|`STRUCT`|[Option](#option)|编排选项
|`STRUCT`|[ConstraintHandle](#constrainthandle)|暂无描述...
</details>
***
## 详情信息
#### func WithAreaConstraint(constraint AreaConstraintHandle[ID, AreaInfo]) AreaOption[ID, AreaInfo]
<span id="WithAreaConstraint"></span>
> 设置编排区域的约束条件
> - 该约束用于判断一个成员是否可以被添加到该编排区域中
> - 与 WithAreaConflict 不同的是,约束通常用于非成员关系导致的硬性约束,例如:成员的等级过滤、成员的性别等
***
#### func WithAreaConflict(conflict AreaConflictHandle[ID, AreaInfo]) AreaOption[ID, AreaInfo]
<span id="WithAreaConflict"></span>
> 设置编排区域的冲突条件,冲突处理函数需要返回造成冲突的成员列表
> - 该冲突用于判断一个成员是否可以被添加到该编排区域中
> - 与 WithAreaConstraint 不同的是,冲突通常用于成员关系导致的软性约束,例如:成员的职业唯一性、成员的种族唯一性等
***
#### func WithAreaEvaluate(evaluate AreaEvaluateHandle[ID, AreaInfo]) AreaOption[ID, AreaInfo]
<span id="WithAreaEvaluate"></span>
> 设置编排区域的评估函数
> - 该评估函数将影响成员被编入区域的优先级
***
#### func NewArrangement(options ...Option[ID, AreaInfo]) *Arrangement[ID, AreaInfo]
<span id="NewArrangement"></span>
> 创建一个新的编排
***
#### func WithItemFixed(matcher ItemFixedAreaHandle[AreaInfo]) ItemOption[ID, AreaInfo]
<span id="WithItemFixed"></span>
> 设置成员的固定编排区域
***
#### func WithItemPriority(priority ItemPriorityHandle[ID, AreaInfo]) ItemOption[ID, AreaInfo]
<span id="WithItemPriority"></span>
> 设置成员的优先级
***
#### func WithItemNotAllow(verify ItemNotAllowVerifyHandle[ID, AreaInfo]) ItemOption[ID, AreaInfo]
<span id="WithItemNotAllow"></span>
> 设置成员不允许的编排区域
***
#### func WithRetryThreshold(threshold int) Option[ID, AreaInfo]
<span id="WithRetryThreshold"></span>
> 设置编排时的重试阈值
> - 当每一轮编排结束任有成员未被编排时,将会进行下一轮编排,直到编排次数达到该阈值
> - 默认的阈值为 10 次
***
#### func WithConstraintHandle(handle ConstraintHandle[ID, AreaInfo]) Option[ID, AreaInfo]
<span id="WithConstraintHandle"></span>
@@ -94,6 +105,7 @@ arrangement 包提供了一些有用的函数来处理数组的排列。
> - 当所有的约束处理函数都无法处理约束时,将会进入下一个编排区域的尝试,如果均无法完成,将会将该成员加入到编排队列的末端,等待下一次编排
>
> 有意思的是,硬性约束应该永远是无解的,而当需要进行一些打破规则的操作时,则可以透过该函数传入的 editor 进行操作
***
#### func WithConflictHandle(handle ConflictHandle[ID, AreaInfo]) Option[ID, AreaInfo]
<span id="WithConflictHandle"></span>
@@ -101,8 +113,9 @@ arrangement 包提供了一些有用的函数来处理数组的排列。
> - 当冲突条件触发时,将会调用该函数。如果无法在该函数中处理冲突,应该继续返回这一批成员,尝试进行下一层的冲突处理
> - 当该函数的返回值长度为 0 时,表示冲突已经被处理,将会命中当前的编排区域
> - 当所有的冲突处理函数都无法处理冲突时,将会进入下一个编排区域的尝试,如果均无法完成,将会将该成员加入到编排队列的末端,等待下一次编排
***
### Area
### Area `STRUCT`
编排区域
```go
type Area[ID comparable, AreaInfo any] struct {
@@ -113,17 +126,17 @@ type Area[ID comparable, AreaInfo any] struct {
evaluate AreaEvaluateHandle[ID, AreaInfo]
}
```
### AreaOption
### AreaOption `STRUCT`
编排区域选项
```go
type AreaOption[ID comparable, AreaInfo any] struct{}
type AreaOption[ID comparable, AreaInfo any] func(area *Area[ID, AreaInfo])
```
### AreaConstraintHandle
### AreaConstraintHandle `STRUCT`
```go
type AreaConstraintHandle[ID comparable, AreaInfo any] struct{}
type AreaConstraintHandle[ID comparable, AreaInfo any] func(area *Area[ID, AreaInfo], item Item[ID]) error
```
### Arrangement
### Arrangement `STRUCT`
用于针对多条数据进行合理编排的数据结构
- 我不知道这个数据结构的具体用途,但是我觉得这个数据结构应该是有用的
- 目前我能想到的用途只有我的过往经历:排课
@@ -140,7 +153,7 @@ type Arrangement[ID comparable, AreaInfo any] struct {
conflictHandles []ConflictHandle[ID, AreaInfo]
}
```
### Editor
### Editor `STRUCT`
提供了大量辅助函数的编辑器
```go
type Editor[ID comparable, AreaInfo any] struct {
@@ -151,28 +164,31 @@ type Editor[ID comparable, AreaInfo any] struct {
retryCount int
}
```
### Item
### Item `INTERFACE`
编排成员
```go
type Item[ID comparable] struct{}
type Item[ID comparable] interface {
GetID() ID
Equal(item Item[ID]) bool
}
```
### ItemOption
### ItemOption `STRUCT`
编排成员选项
```go
type ItemOption[ID comparable, AreaInfo any] struct{}
type ItemOption[ID comparable, AreaInfo any] func(arrangement *Arrangement[ID, AreaInfo], item Item[ID])
```
### ItemFixedAreaHandle
### ItemFixedAreaHandle `STRUCT`
```go
type ItemFixedAreaHandle[AreaInfo any] struct{}
type ItemFixedAreaHandle[AreaInfo any] func(areaInfo AreaInfo) bool
```
### Option
### Option `STRUCT`
编排选项
```go
type Option[ID comparable, AreaInfo any] struct{}
type Option[ID comparable, AreaInfo any] func(arrangement *Arrangement[ID, AreaInfo])
```
### ConstraintHandle
### ConstraintHandle `STRUCT`
```go
type ConstraintHandle[ID comparable, AreaInfo any] struct{}
type ConstraintHandle[ID comparable, AreaInfo any] func(editor *Editor[ID, AreaInfo], area *Area[ID, AreaInfo], item Item[ID], err error) error
```

View File

@@ -1,5 +1,8 @@
# Buffer
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/buffer)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
buffer 提供了缓冲区相关的实用程序。
包括创建、读取和写入缓冲区的函数。
@@ -8,45 +11,67 @@ buffer 提供了缓冲区相关的实用程序。
无界缓冲区的所有方法都是线程安全的,除了用于同步的互斥锁外,不会阻塞任何东西。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/buffer)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewRing](#NewRing)|创建一个并发不安全的环形缓冲区
|[NewRingUnbounded](#NewRingUnbounded)|创建一个并发安全的基于环形缓冲区实现的无界缓冲区
|[NewUnbounded](#NewUnbounded)|创建一个无界缓冲区
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Ring](#ring)|环形缓冲区
|[RingUnbounded](#ringunbounded)|基于环形缓冲区实现的无界缓冲区
|[Unbounded](#unbounded)|是无界缓冲区的实现
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Ring](#ring)|环形缓冲区
|`STRUCT`|[RingUnbounded](#ringunbounded)|基于环形缓冲区实现的无界缓冲区
|`STRUCT`|[Unbounded](#unbounded)|是无界缓冲区的实现
</details>
***
## 详情信息
#### func NewRing(initSize ...int) *Ring[T]
<span id="NewRing"></span>
> 创建一个并发不安全的环形缓冲区
> - initSize: 初始容量
>
> 当初始容量小于 2 或未设置时,将会使用默认容量 2
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewRing(t *testing.T) {
ring := buffer.NewRing[int]()
for i := 0; i < 100; i++ {
ring.Write(i)
t.Log(ring.Read())
}
}
```
</details>
***
#### func NewRingUnbounded(bufferSize int) *RingUnbounded[T]
<span id="NewRingUnbounded"></span>
> 创建一个并发安全的基于环形缓冲区实现的无界缓冲区
***
#### func NewUnbounded() *Unbounded[V]
<span id="NewUnbounded"></span>
@@ -55,8 +80,9 @@ buffer 提供了缓冲区相关的实用程序。
>
> 该缓冲区来源于 gRPC 的实现,用于在不使用额外 goroutine 的情况下实现无界缓冲区
> - 该缓冲区的所有方法都是线程安全的,除了用于同步的互斥锁外,不会阻塞任何东西
***
### Ring
### Ring `STRUCT`
环形缓冲区
```go
type Ring[T any] struct {
@@ -69,6 +95,29 @@ type Ring[T any] struct {
```
#### func (*Ring) Read() T, error
> 读取数据
<details>
<summary>查看 / 收起基准测试</summary>
```go
func BenchmarkRing_Read(b *testing.B) {
ring := buffer.NewRing[int](1024)
for i := 0; i < b.N; i++ {
ring.Write(i)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = ring.Read()
}
}
```
</details>
***
#### func (*Ring) ReadAll() []T
> 读取所有数据
@@ -78,6 +127,26 @@ type Ring[T any] struct {
***
#### func (*Ring) Write(v T)
> 写入数据
<details>
<summary>查看 / 收起基准测试</summary>
```go
func BenchmarkRing_Write(b *testing.B) {
ring := buffer.NewRing[int](1024)
b.ResetTimer()
for i := 0; i < b.N; i++ {
ring.Write(i)
}
}
```
</details>
***
#### func (*Ring) IsEmpty() bool
> 是否为空
@@ -91,7 +160,7 @@ type Ring[T any] struct {
#### func (*Ring) Reset()
> 重置缓冲区
***
### RingUnbounded
### RingUnbounded `STRUCT`
基于环形缓冲区实现的无界缓冲区
```go
type RingUnbounded[T any] struct {
@@ -106,17 +175,87 @@ type RingUnbounded[T any] struct {
```
#### func (*RingUnbounded) Write(v T)
> 写入数据
<details>
<summary>查看 / 收起基准测试</summary>
```go
func BenchmarkRingUnbounded_Write(b *testing.B) {
ring := buffer.NewRingUnbounded[int](1024 * 16)
b.ResetTimer()
for i := 0; i < b.N; i++ {
ring.Write(i)
}
}
```
</details>
***
#### func (*RingUnbounded) Read() chan T
> 读取数据
<details>
<summary>查看 / 收起基准测试</summary>
```go
func BenchmarkRingUnbounded_Read(b *testing.B) {
ring := buffer.NewRingUnbounded[int](1024 * 16)
for i := 0; i < b.N; i++ {
ring.Write(i)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
<-ring.Read()
}
}
```
</details>
***
#### func (*RingUnbounded) Closed() bool
> 判断缓冲区是否已关闭
***
#### func (*RingUnbounded) Close() chan struct {}
> 关闭缓冲区,关闭后将不再接收新数据,但是已有数据仍然可以读取
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestRingUnbounded_Close(t *testing.T) {
ring := buffer.NewRingUnbounded[int](1024 * 16)
for i := 0; i < 100; i++ {
ring.Write(i)
}
t.Log("write done")
ring.Close()
t.Log("close done")
for v := range ring.Read() {
ring.Write(v)
t.Log(v)
}
t.Log("read done")
}
```
</details>
***
### Unbounded
### Unbounded `STRUCT`
是无界缓冲区的实现
```go
type Unbounded[V any] struct {
@@ -135,6 +274,27 @@ type Unbounded[V any] struct {
***
#### func (*Unbounded) Get() chan V
> 获取读取通道
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestUnbounded_Get(t *testing.T) {
ub := buffer.NewUnbounded[int]()
for i := 0; i < 100; i++ {
ub.Put(i + 1)
fmt.Println(<-ub.Get())
ub.Load()
}
}
```
</details>
***
#### func (*Unbounded) Close()
> 关闭

View File

@@ -5,7 +5,7 @@ import (
"testing"
)
func BenchmarkRingWrite(b *testing.B) {
func BenchmarkRing_Write(b *testing.B) {
ring := buffer.NewRing[int](1024)
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -13,7 +13,7 @@ func BenchmarkRingWrite(b *testing.B) {
}
}
func BenchmarkRingRead(b *testing.B) {
func BenchmarkRing_Read(b *testing.B) {
ring := buffer.NewRing[int](1024)
for i := 0; i < b.N; i++ {
ring.Write(i)

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,20 @@
# Listings
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/listings)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewMatrix](#NewMatrix)|创建一个新的 Matrix 实例。
|[NewPagedSlice](#NewPagedSlice)|创建一个新的 PagedSlice 实例。
@@ -21,35 +22,41 @@
|[NewSyncSlice](#NewSyncSlice)|创建一个 SyncSlice
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Matrix](#matrix)|暂无描述...
|[PagedSlice](#pagedslice)|是一个高效的动态数组,它通过分页管理内存并减少频繁的内存分配来提高性能。
|[PrioritySlice](#priorityslice)|是一个优先级切片
|[SyncSlice](#syncslice)|是基于 sync.RWMutex 实现的线程安全的 slice
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Matrix](#matrix)|暂无描述...
|`STRUCT`|[PagedSlice](#pagedslice)|是一个高效的动态数组,它通过分页管理内存并减少频繁的内存分配来提高性能。
|`STRUCT`|[PrioritySlice](#priorityslice)|是一个优先级切片
|`STRUCT`|[SyncSlice](#syncslice)|是基于 sync.RWMutex 实现的线程安全的 slice
</details>
***
## 详情信息
#### func NewMatrix(dimensions ...int) *Matrix[V]
<span id="NewMatrix"></span>
> 创建一个新的 Matrix 实例。
***
#### func NewPagedSlice(pageSize int) *PagedSlice[T]
<span id="NewPagedSlice"></span>
> 创建一个新的 PagedSlice 实例。
***
#### func NewPrioritySlice(lengthAndCap ...int) *PrioritySlice[V]
<span id="NewPrioritySlice"></span>
> 创建一个优先级切片
***
#### func NewSyncSlice(length int, cap int) *SyncSlice[V]
<span id="NewSyncSlice"></span>
> 创建一个 SyncSlice
***
### Matrix
### Matrix `STRUCT`
```go
type Matrix[V any] struct {
@@ -69,7 +76,7 @@ type Matrix[V any] struct {
#### func (*Matrix) Clear()
> 清空矩阵。
***
### PagedSlice
### PagedSlice `STRUCT`
是一个高效的动态数组,它通过分页管理内存并减少频繁的内存分配来提高性能。
```go
type PagedSlice[T any] struct {
@@ -97,7 +104,7 @@ type PagedSlice[T any] struct {
#### func (*PagedSlice) Range(f func (index int, value T) bool)
> 迭代 PagedSlice 中的所有元素。
***
### PrioritySlice
### PrioritySlice `STRUCT`
是一个优先级切片
```go
type PrioritySlice[V any] struct {
@@ -115,6 +122,25 @@ type PrioritySlice[V any] struct {
***
#### func (*PrioritySlice) Append(v V, p int)
> 添加元素
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestPrioritySlice_Append(t *testing.T) {
var s = listings.NewPrioritySlice[string]()
s.Append("name_1", 2)
s.Append("name_2", 1)
fmt.Println(s)
}
```
</details>
***
#### func (*PrioritySlice) Appends(priority int, vs ...V)
> 添加元素
@@ -155,7 +181,7 @@ type PrioritySlice[V any] struct {
#### func (*PrioritySlice) String() string
> 返回切片字符串
***
### SyncSlice
### SyncSlice `STRUCT`
是基于 sync.RWMutex 实现的线程安全的 slice
```go
type SyncSlice[V any] struct {

View File

@@ -1,37 +1,41 @@
# Mappings
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/mappings)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewSyncMap](#NewSyncMap)|创建一个 SyncMap
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[SyncMap](#syncmap)|是基于 sync.RWMutex 实现的线程安全的 map
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[SyncMap](#syncmap)|是基于 sync.RWMutex 实现的线程安全的 map
</details>
***
## 详情信息
#### func NewSyncMap(source ...map[K]V) *SyncMap[K, V]
<span id="NewSyncMap"></span>
> 创建一个 SyncMap
***
### SyncMap
### SyncMap `STRUCT`
是基于 sync.RWMutex 实现的线程安全的 map
- 适用于要考虑并发读写但是并发读写的频率不高的情况
```go

View File

@@ -1,19 +1,20 @@
# Combination
combination 包提供了一些实用的组合函数。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/combination)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
combination 包提供了一些实用的组合函数。
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewCombination](#NewCombination)|创建一个新的组合器
|[WithEvaluation](#WithEvaluation)|设置组合评估函数
@@ -47,24 +48,27 @@ combination 包提供了一些实用的组合函数。
|[WithValidatorHandleNCarryIndependentM](#WithValidatorHandleNCarryIndependentM)|校验组合成员是否匹配 N 携带独立的 M 的组合
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Combination](#combination)|用于从多个匹配器内提取组合的数据结构
|[Option](#option)|组合器选项
|[Item](#item)|暂无描述...
|[Matcher](#matcher)|用于从一组数据内提取组合的数据结构
|[MatcherOption](#matcheroption)|匹配器选项
|[Validator](#validator)|用于对组合进行验证的校验器
|[ValidatorOption](#validatoroption)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Combination](#combination)|用于从多个匹配器内提取组合的数据结构
|`STRUCT`|[Option](#option)|组合器选项
|`INTERFACE`|[Item](#item)|暂无描述...
|`STRUCT`|[Matcher](#matcher)|用于从一组数据内提取组合的数据结构
|`STRUCT`|[MatcherOption](#matcheroption)|匹配器选项
|`STRUCT`|[Validator](#validator)|用于对组合进行验证的校验器
|`STRUCT`|[ValidatorOption](#validatoroption)|暂无描述...
</details>
***
## 详情信息
#### func NewCombination(options ...Option[T]) *Combination[T]
<span id="NewCombination"></span>
> 创建一个新的组合器
***
#### func WithEvaluation(evaluate func (items []T) float64) Option[T]
<span id="WithEvaluation"></span>
@@ -73,48 +77,57 @@ combination 包提供了一些实用的组合函数。
> - 通过该选项将设置所有匹配器的默认评估函数为该函数
> - 通过匹配器选项 WithMatcherEvaluation 可以覆盖该默认评估函数
> - 默认的评估函数将返回一个随机数
***
#### func NewMatcher(options ...MatcherOption[T]) *Matcher[T]
<span id="NewMatcher"></span>
> 创建一个新的匹配器
***
#### func WithMatcherEvaluation(evaluate func (items []T) float64) MatcherOption[T]
<span id="WithMatcherEvaluation"></span>
> 设置匹配器评估函数
> - 用于对组合进行评估,返回一个分值的评价函数
> - 通过该选项将覆盖匹配器的默认(WithEvaluation)评估函数
***
#### func WithMatcherLeastLength(length int) MatcherOption[T]
<span id="WithMatcherLeastLength"></span>
> 通过匹配最小长度的组合创建匹配器
> - length: 组合的长度,表示需要匹配的组合最小数量
***
#### func WithMatcherLength(length int) MatcherOption[T]
<span id="WithMatcherLength"></span>
> 通过匹配长度的组合创建匹配器
> - length: 组合的长度,表示需要匹配的组合数量
***
#### func WithMatcherMostLength(length int) MatcherOption[T]
<span id="WithMatcherMostLength"></span>
> 通过匹配最大长度的组合创建匹配器
> - length: 组合的长度,表示需要匹配的组合最大数量
***
#### func WithMatcherIntervalLength(min int, max int) MatcherOption[T]
<span id="WithMatcherIntervalLength"></span>
> 通过匹配长度区间的组合创建匹配器
> - min: 组合的最小长度,表示需要匹配的组合最小数量
> - max: 组合的最大长度,表示需要匹配的组合最大数量
***
#### func WithMatcherContinuity(getIndex func (item T) Index) MatcherOption[T]
<span id="WithMatcherContinuity"></span>
> 通过匹配连续的组合创建匹配器
> - index: 用于获取组合中元素的索引值,用于判断是否连续
***
#### func WithMatcherSame(count int, getType func (item T) E) MatcherOption[T]
<span id="WithMatcherSame"></span>
> 通过匹配相同的组合创建匹配器
> - count: 组合中相同元素的数量,当 count <= 0 时,表示相同元素的数量不限
> - getType: 用于获取组合中元素的类型,用于判断是否相同
***
#### func WithMatcherNCarryM(n int, m int, getType func (item T) E) MatcherOption[T]
<span id="WithMatcherNCarryM"></span>
@@ -122,6 +135,7 @@ combination 包提供了一些实用的组合函数。
> - n: 组合中元素的数量表示需要匹配的组合数量n 的类型需要全部相同
> - m: 组合中元素的数量表示需要匹配的组合数量m 的类型需要全部相同
> - getType: 用于获取组合中元素的类型,用于判断是否相同
***
#### func WithMatcherNCarryIndependentM(n int, m int, getType func (item T) E) MatcherOption[T]
<span id="WithMatcherNCarryIndependentM"></span>
@@ -129,70 +143,87 @@ combination 包提供了一些实用的组合函数。
> - n: 组合中元素的数量表示需要匹配的组合数量n 的类型需要全部相同
> - m: 组合中元素的数量表示需要匹配的组合数量m 的类型无需全部相同
> - getType: 用于获取组合中元素的类型,用于判断是否相同
***
#### func NewValidator(options ...ValidatorOption[T]) *Validator[T]
<span id="NewValidator"></span>
> 创建一个新的校验器
***
#### func WithValidatorHandle(handle func (items []T) bool) ValidatorOption[T]
<span id="WithValidatorHandle"></span>
> 通过特定的验证函数对组合进行验证
***
#### func WithValidatorHandleLength(length int) ValidatorOption[T]
<span id="WithValidatorHandleLength"></span>
> 校验组合的长度是否符合要求
***
#### func WithValidatorHandleLengthRange(min int, max int) ValidatorOption[T]
<span id="WithValidatorHandleLengthRange"></span>
> 校验组合的长度是否在指定的范围内
***
#### func WithValidatorHandleLengthMin(min int) ValidatorOption[T]
<span id="WithValidatorHandleLengthMin"></span>
> 校验组合的长度是否大于等于指定的最小值
***
#### func WithValidatorHandleLengthMax(max int) ValidatorOption[T]
<span id="WithValidatorHandleLengthMax"></span>
> 校验组合的长度是否小于等于指定的最大值
***
#### func WithValidatorHandleLengthNot(length int) ValidatorOption[T]
<span id="WithValidatorHandleLengthNot"></span>
> 校验组合的长度是否不等于指定的值
***
#### func WithValidatorHandleTypeLength(length int, getType func (item T) E) ValidatorOption[T]
<span id="WithValidatorHandleTypeLength"></span>
> 校验组合成员类型数量是否为指定的值
***
#### func WithValidatorHandleTypeLengthRange(min int, max int, getType func (item T) E) ValidatorOption[T]
<span id="WithValidatorHandleTypeLengthRange"></span>
> 校验组合成员类型数量是否在指定的范围内
***
#### func WithValidatorHandleTypeLengthMin(min int, getType func (item T) E) ValidatorOption[T]
<span id="WithValidatorHandleTypeLengthMin"></span>
> 校验组合成员类型数量是否大于等于指定的最小值
***
#### func WithValidatorHandleTypeLengthMax(max int, getType func (item T) E) ValidatorOption[T]
<span id="WithValidatorHandleTypeLengthMax"></span>
> 校验组合成员类型数量是否小于等于指定的最大值
***
#### func WithValidatorHandleTypeLengthNot(length int, getType func (item T) E) ValidatorOption[T]
<span id="WithValidatorHandleTypeLengthNot"></span>
> 校验组合成员类型数量是否不等于指定的值
***
#### func WithValidatorHandleContinuous(getIndex func (item T) Index) ValidatorOption[T]
<span id="WithValidatorHandleContinuous"></span>
> 校验组合成员是否连续
***
#### func WithValidatorHandleContinuousNot(getIndex func (item T) Index) ValidatorOption[T]
<span id="WithValidatorHandleContinuousNot"></span>
> 校验组合成员是否不连续
***
#### func WithValidatorHandleGroupContinuous(getType func (item T) E, getIndex func (item T) Index) ValidatorOption[T]
<span id="WithValidatorHandleGroupContinuous"></span>
> 校验组合成员是否能够按类型分组并且连续
***
#### func WithValidatorHandleGroupContinuousN(n int, getType func (item T) E, getIndex func (item T) Index) ValidatorOption[T]
<span id="WithValidatorHandleGroupContinuousN"></span>
> 校验组合成员是否能够按分组为 n 组类型并且连续
***
#### func WithValidatorHandleNCarryM(n int, m int, getType func (item T) E) ValidatorOption[T]
<span id="WithValidatorHandleNCarryM"></span>
@@ -200,6 +231,7 @@ combination 包提供了一些实用的组合函数。
> - n: 组合中元素的数量表示需要匹配的组合数量n 的类型需要全部相同
> - m: 组合中元素的数量表示需要匹配的组合数量m 的类型需要全部相同
> - getType: 用于获取组合中元素的类型,用于判断是否相同
***
#### func WithValidatorHandleNCarryIndependentM(n int, m int, getType func (item T) E) ValidatorOption[T]
<span id="WithValidatorHandleNCarryIndependentM"></span>
@@ -207,8 +239,9 @@ combination 包提供了一些实用的组合函数。
> - n: 组合中元素的数量表示需要匹配的组合数量n 的类型需要全部相同
> - m: 组合中元素的数量表示需要匹配的组合数量m 的类型无需全部相同
> - getType: 用于获取组合中元素的类型,用于判断是否相同
***
### Combination
### Combination `STRUCT`
用于从多个匹配器内提取组合的数据结构
```go
type Combination[T Item] struct {
@@ -234,21 +267,54 @@ type Combination[T Item] struct {
***
#### func (*Combination) Best(items []T) (name string, result []T)
> 从一组数据中提取符合匹配器规则的最佳组合
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestCombination_Best(t *testing.T) {
combine := combination.NewCombination(combination.WithEvaluation(func(items []*Poker) float64 {
var total float64
for _, item := range items {
total += float64(item.Point)
}
return total
}))
combine.NewMatcher("炸弹", combination.WithMatcherSame[*Poker, int](4, func(item *Poker) int {
return item.Point
})).NewMatcher("三带一", combination.WithMatcherNCarryM[*Poker, int](3, 1, func(item *Poker) int {
return item.Point
}))
var cards = []*Poker{{Point: 2, Color: 1}, {Point: 2, Color: 2}, {Point: 2, Color: 3}, {Point: 3, Color: 4}, {Point: 4, Color: 1}, {Point: 4, Color: 2}, {Point: 5, Color: 3}, {Point: 6, Color: 4}, {Point: 7, Color: 1}, {Point: 8, Color: 2}, {Point: 9, Color: 3}, {Point: 10, Color: 4}, {Point: 11, Color: 1}, {Point: 12, Color: 2}, {Point: 13, Color: 3}, {Point: 10, Color: 3}, {Point: 11, Color: 2}, {Point: 12, Color: 1}, {Point: 13, Color: 4}, {Point: 10, Color: 2}}
name, result := combine.Worst(cards)
fmt.Println("best:", name)
for _, item := range result {
fmt.Println(item)
}
}
```
</details>
***
#### func (*Combination) Worst(items []T) (name string, result []T)
> 从一组数据中提取符合匹配器规则的最差组合
***
### Option
### Option `STRUCT`
组合器选项
```go
type Option[T Item] struct{}
type Option[T Item] func(*Combination[T])
```
### Item
### Item `INTERFACE`
```go
type Item struct{}
type Item interface{}
```
### Matcher
### Matcher `STRUCT`
用于从一组数据内提取组合的数据结构
```go
type Matcher[T Item] struct {
@@ -269,12 +335,12 @@ type Matcher[T Item] struct {
#### func (*Matcher) Worst(items []T) []T
> 从一组数据中提取符筛选器规则的最差组合
***
### MatcherOption
### MatcherOption `STRUCT`
匹配器选项
```go
type MatcherOption[T Item] struct{}
type MatcherOption[T Item] func(matcher *Matcher[T])
```
### Validator
### Validator `STRUCT`
用于对组合进行验证的校验器
```go
type Validator[T Item] struct {
@@ -283,9 +349,41 @@ type Validator[T Item] struct {
```
#### func (*Validator) Validate(items []T) bool
> 校验组合是否符合要求
***
### ValidatorOption
<details>
<summary>查看 / 收起单元测试</summary>
```go
type ValidatorOption[T Item] struct{}
func TestValidator_Validate(t *testing.T) {
v := combination.NewValidator[*Card](combination.WithValidatorHandleContinuous[*Card, int](func(item *Card) int {
switch item.Point {
case "A":
return 1
case "2", "3", "4", "5", "6", "7", "8", "9", "10":
return super.StringToInt(item.Point)
case "J":
return 11
case "Q":
return 12
case "K":
return 13
}
return -1
}), combination.WithValidatorHandleLength[*Card](3))
cards := []*Card{{Point: "2", Color: "Spade"}, {Point: "4", Color: "Heart"}, {Point: "3", Color: "Diamond"}}
fmt.Println(v.Validate(cards))
}
```
</details>
***
### ValidatorOption `STRUCT`
```go
type ValidatorOption[T Item] func(validator *Validator[T])
```

View File

@@ -1,19 +1,20 @@
# Compress
compress 提供了一些用于压缩和解压缩数据的函数。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/compress)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
compress 提供了一些用于压缩和解压缩数据的函数。
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[GZipCompress](#GZipCompress)|对数据进行GZip压缩返回bytes.Buffer和错误信息
|[GZipUnCompress](#GZipUnCompress)|对已进行GZip压缩的数据进行解压缩返回字节数组及错误信息
@@ -23,35 +24,35 @@ compress 提供了一些用于压缩和解压缩数据的函数。
|[ZIPUnCompress](#ZIPUnCompress)|对已进行ZIP压缩的数据进行解压缩返回字节数组及错误信息
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息
#### func GZipCompress(data []byte) bytes.Buffer, error
<span id="GZipCompress"></span>
> 对数据进行GZip压缩返回bytes.Buffer和错误信息
***
#### func GZipUnCompress(dataByte []byte) []byte, error
<span id="GZipUnCompress"></span>
> 对已进行GZip压缩的数据进行解压缩返回字节数组及错误信息
***
#### func TARCompress(data []byte) bytes.Buffer, error
<span id="TARCompress"></span>
> 对数据进行TAR压缩返回bytes.Buffer和错误信息
***
#### func TARUnCompress(dataByte []byte) []byte, error
<span id="TARUnCompress"></span>
> 对已进行TAR压缩的数据进行解压缩返回字节数组及错误信息
***
#### func ZIPCompress(data []byte) bytes.Buffer, error
<span id="ZIPCompress"></span>
> 对数据进行ZIP压缩返回bytes.Buffer和错误信息
***
#### func ZIPUnCompress(dataByte []byte) []byte, error
<span id="ZIPUnCompress"></span>
> 对已进行ZIP压缩的数据进行解压缩返回字节数组及错误信息
***

View File

@@ -1,19 +1,20 @@
# Crypto
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/crypto)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[EncryptBase64](#EncryptBase64)|对数据进行Base64编码
|[DecodedBase64](#DecodedBase64)|对数据进行Base64解码
@@ -27,51 +28,55 @@
|[DecodedSHA256](#DecodedSHA256)|对字节数组进行SHA256加密并返回其结果。
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息
#### func EncryptBase64(data []byte) string
<span id="EncryptBase64"></span>
> 对数据进行Base64编码
***
#### func DecodedBase64(data string) []byte, error
<span id="DecodedBase64"></span>
> 对数据进行Base64解码
***
#### func EncryptCRC32(str string) uint32
<span id="EncryptCRC32"></span>
> 对字符串进行CRC加密并返回其结果。
***
#### func DecodedCRC32(data []byte) uint32
<span id="DecodedCRC32"></span>
> 对字节数组进行CRC加密并返回其结果。
***
#### func EncryptMD5(str string) string
<span id="EncryptMD5"></span>
> 对字符串进行MD5加密并返回其结果。
***
#### func DecodedMD5(data []byte) string
<span id="DecodedMD5"></span>
> 对字节数组进行MD5加密并返回其结果。
***
#### func EncryptSHA1(str string) string
<span id="EncryptSHA1"></span>
> 对字符串进行SHA1加密并返回其结果。
***
#### func DecodedSHA1(data []byte) string
<span id="DecodedSHA1"></span>
> 对字节数组进行SHA1加密并返回其结果。
***
#### func EncryptSHA256(str string) string
<span id="EncryptSHA256"></span>
> 对字符串进行SHA256加密并返回其结果。
***
#### func DecodedSHA256(data []byte) string
<span id="DecodedSHA256"></span>
> 对字节数组进行SHA256加密并返回其结果。
***

View File

@@ -1,44 +1,49 @@
# Deck
deck 包中的内容用于针对一堆内容的管理,适用但不限于牌堆、麻将牌堆等情况。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/deck)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
deck 包中的内容用于针对一堆内容的管理,适用但不限于牌堆、麻将牌堆等情况。
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewDeck](#NewDeck)|创建一个新的甲板
|[NewGroup](#NewGroup)|创建一个新的组
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Deck](#deck)|甲板,用于针对一堆 Group 进行管理的数据结构
|[Group](#group)|甲板中的组,用于针对一堆内容进行管理的数据结构
|[Item](#item)|甲板成员
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Deck](#deck)|甲板,用于针对一堆 Group 进行管理的数据结构
|`STRUCT`|[Group](#group)|甲板中的组,用于针对一堆内容进行管理的数据结构
|`INTERFACE`|[Item](#item)|甲板成员
</details>
***
## 详情信息
#### func NewDeck() *Deck[I]
<span id="NewDeck"></span>
> 创建一个新的甲板
***
#### func NewGroup(guid int64, fillHandle func (guid int64) []I) *Group[I]
<span id="NewGroup"></span>
> 创建一个新的组
***
### Deck
### Deck `STRUCT`
甲板,用于针对一堆 Group 进行管理的数据结构
```go
type Deck[I Item] struct {
@@ -67,7 +72,7 @@ type Deck[I Item] struct {
#### func (*Deck) GetPrev(guid int64) *Group[I]
> 获取特定组的上一个组
***
### Group
### Group `STRUCT`
甲板中的组,用于针对一堆内容进行管理的数据结构
```go
type Group[I Item] struct {
@@ -121,8 +126,8 @@ type Group[I Item] struct {
#### func (*Group) GetItem(index int) I
> 获取组中的指定内容
***
### Item
### Item `INTERFACE`
甲板成员
```go
type Item struct{}
type Item interface{}
```

View File

@@ -1,19 +1,20 @@
# File
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/file)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[PathExist](#PathExist)|路径是否存在
|[IsDir](#IsDir)|路径是否是文件夹
@@ -28,57 +29,60 @@
|[FindLineChunksByOffset](#FindLineChunksByOffset)|该函数与 FindLineChunks 类似,不同的是该函数可以指定 offset 从指定位置开始读取文件
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息
#### func PathExist(path string) bool, error
<span id="PathExist"></span>
> 路径是否存在
***
#### func IsDir(path string) bool, error
<span id="IsDir"></span>
> 路径是否是文件夹
***
#### func WriterFile(filePath string, content []byte) error
<span id="WriterFile"></span>
> 向特定文件写入内容
***
#### func ReadOnce(filePath string) []byte, error
<span id="ReadOnce"></span>
> 单次读取文件
> - 一次性对整个文件进行读取,小文件读取可以很方便的一次性将文件内容读取出来,而大文件读取会造成性能影响。
***
#### func ReadBlockHook(filePath string, bufferSize int, hook func (data []byte)) error
<span id="ReadBlockHook"></span>
> 分块读取文件
> - 将filePath路径对应的文件数据并将读到的每一部分传入hook函数中当过程中如果产生错误则会返回error。
> - 分块读取可以在读取速度和内存消耗之间有一个很好的平衡。
***
#### func ReadLine(filePath string, hook func (line string)) error
<span id="ReadLine"></span>
> 分行读取文件
> - 将filePath路径对应的文件数据并将读到的每一行传入hook函数中当过程中如果产生错误则会返回error。
***
#### func LineCount(filePath string) int
<span id="LineCount"></span>
> 统计文件行数
***
#### func Paths(dir string) []string
<span id="Paths"></span>
> 获取指定目录下的所有文件路径
> - 包括了子目录下的文件
> - 不包含目录
***
#### func ReadLineWithParallel(filename string, chunkSize int64, handlerFunc func ( string), start ...int64) (n int64, err error)
<span id="ReadLineWithParallel"></span>
> 并行的分行读取文件并行处理,处理过程中会将每一行的内容传入 handlerFunc 中进行处理
> - 由于是并行处理,所以处理过程中的顺序是不确定的。
> - 可通过 start 参数指定开始读取的位置,如果不指定则从文件开头开始读取。
***
#### func FindLineChunks(file *os.File, chunkSize int64) [][2]int64
<span id="FindLineChunks"></span>
@@ -86,8 +90,10 @@
> - 使用该函数得到的分块是完整的行,不会出现行被分割的情况
> - 当过程中发生错误将会发生 panic
> - 返回值的成员是一个长度为 2 的数组,第一个元素是分块的起始位置,第二个元素是分块的结束位置
***
#### func FindLineChunksByOffset(file *os.File, offset int64, chunkSize int64) [][2]int64
<span id="FindLineChunksByOffset"></span>
> 该函数与 FindLineChunks 类似,不同的是该函数可以指定 offset 从指定位置开始读取文件
***

View File

@@ -1,19 +1,20 @@
# Fsm
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/fsm)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewFSM](#NewFSM)|创建一个新的状态机
|[WithEnterBeforeEvent](#WithEnterBeforeEvent)|设置状态进入前的回调
@@ -23,44 +24,52 @@
|[WithExitAfterEvent](#WithExitAfterEvent)|设置状态退出后的回调
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[FSM](#fsm)|状态机
|[Option](#option)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[FSM](#fsm)|状态机
|`STRUCT`|[Option](#option)|暂无描述...
</details>
***
## 详情信息
#### func NewFSM(data Data) *FSM[State, Data]
<span id="NewFSM"></span>
> 创建一个新的状态机
***
#### func WithEnterBeforeEvent(fn func (state *FSM[State, Data])) Option[State, Data]
<span id="WithEnterBeforeEvent"></span>
> 设置状态进入前的回调
> - 在首次设置状态时,状态机本身的当前状态为零值状态
***
#### func WithEnterAfterEvent(fn func (state *FSM[State, Data])) Option[State, Data]
<span id="WithEnterAfterEvent"></span>
> 设置状态进入后的回调
***
#### func WithUpdateEvent(fn func (state *FSM[State, Data])) Option[State, Data]
<span id="WithUpdateEvent"></span>
> 设置状态内刷新的回调
***
#### func WithExitBeforeEvent(fn func (state *FSM[State, Data])) Option[State, Data]
<span id="WithExitBeforeEvent"></span>
> 设置状态退出前的回调
> - 该阶段状态机的状态为退出前的状态,而非新的状态
***
#### func WithExitAfterEvent(fn func (state *FSM[State, Data])) Option[State, Data]
<span id="WithExitAfterEvent"></span>
> 设置状态退出后的回调
> - 该阶段状态机的状态为新的状态,而非退出前的状态
***
### FSM
### FSM `STRUCT`
状态机
```go
type FSM[State comparable, Data any] struct {
@@ -75,8 +84,8 @@ type FSM[State comparable, Data any] struct {
exitAfterEventHandles map[State][]func(state *FSM[State, Data])
}
```
### Option
### Option `STRUCT`
```go
type Option[State comparable, Data any] struct{}
type Option[State comparable, Data any] func(fsm *FSM[State, Data], state State)
```

View File

@@ -1,42 +1,66 @@
# Astgo
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/astgo)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewPackage](#NewPackage)|暂无描述...
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Comment](#comment)|暂无描述...
|[Field](#field)|暂无描述...
|[File](#file)|暂无描述...
|[Function](#function)|暂无描述...
|[Package](#package)|暂无描述...
|[Struct](#struct)|暂无描述...
|[Type](#type)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Comment](#comment)|暂无描述...
|`STRUCT`|[Field](#field)|暂无描述...
|`STRUCT`|[File](#file)|暂无描述...
|`STRUCT`|[Function](#function)|暂无描述...
|`STRUCT`|[Package](#package)|暂无描述...
|`STRUCT`|[Struct](#struct)|暂无描述...
|`STRUCT`|[Type](#type)|暂无描述...
</details>
***
## 详情信息
#### func NewPackage(dir string) *Package, error
<span id="NewPackage"></span>
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewPackage(t *testing.T) {
p, err := astgo.NewPackage(`/Users/kercylan/Coding.localized/Go/minotaur/server`)
if err != nil {
panic(err)
}
fmt.Println(string(super.MarshalIndentJSON(p, "", " ")))
}
```
</details>
***
### Comment
### Comment `STRUCT`
```go
type Comment struct {
@@ -44,7 +68,7 @@ type Comment struct {
Clear []string
}
```
### Field
### Field `STRUCT`
```go
type Field struct {
@@ -54,7 +78,7 @@ type Field struct {
Comments *Comment
}
```
### File
### File `STRUCT`
```go
type File struct {
@@ -68,10 +92,11 @@ type File struct {
```
#### func (*File) Package() string
***
### Function
### Function `STRUCT`
```go
type Function struct {
decl *ast.FuncDecl
Name string
Internal bool
Generic []*Field
@@ -85,14 +110,17 @@ type Function struct {
Test bool
}
```
### Package
#### func (*Function) Code() string
***
### Package `STRUCT`
```go
type Package struct {
Dir string
Name string
Dirs []string
Files []*File
Dir string
Name string
Dirs []string
Files []*File
Functions map[string]*Function
}
```
#### func (*Package) StructFunc(name string) []*Function
@@ -103,19 +131,27 @@ type Package struct {
***
#### func (*Package) FileComments() *Comment
***
### Struct
#### func (*Package) GetUnitTest(f *Function) *Function
***
#### func (*Package) GetExampleTest(f *Function) *Function
***
#### func (*Package) GetBenchmarkTest(f *Function) *Function
***
### Struct `STRUCT`
```go
type Struct struct {
Name string
Internal bool
Comments *Comment
Generic []*Field
Fields []*Field
Test bool
Name string
Internal bool
Interface bool
Comments *Comment
Generic []*Field
Fields []*Field
Type *Type
Test bool
}
```
### Type
### Type `STRUCT`
```go
type Type struct {

View File

@@ -1,6 +1,7 @@
package astgo
import (
"fmt"
"go/ast"
)
@@ -14,6 +15,9 @@ func newField(field *ast.Field) []*Field {
} else {
var fs []*Field
for _, name := range field.Names {
if name.String() == "Format" {
fmt.Println()
}
fs = append(fs, &Field{
Anonymous: false,
Name: name.String(),

View File

@@ -1,12 +1,16 @@
package astgo
import (
"bytes"
"go/ast"
"go/format"
"go/token"
"strings"
)
func newFunction(astFunc *ast.FuncDecl) *Function {
f := &Function{
decl: astFunc,
Name: astFunc.Name.String(),
Comments: newComment(astFunc.Doc),
}
@@ -37,6 +41,7 @@ func newFunction(astFunc *ast.FuncDecl) *Function {
}
type Function struct {
decl *ast.FuncDecl
Name string // 函数名
Internal bool // 内部函数
Generic []*Field // 泛型定义
@@ -49,3 +54,11 @@ type Function struct {
IsBenchmark bool // 是否为基准测试
Test bool // 是否为测试函数
}
func (f *Function) Code() string {
var bb bytes.Buffer
if err := format.Node(&bb, token.NewFileSet(), f.decl); err != nil {
panic(err)
}
return bb.String() + "\n"
}

View File

@@ -2,12 +2,14 @@ package astgo
import (
"errors"
"fmt"
"github.com/kercylan98/minotaur/utils/str"
"os"
"path/filepath"
)
func NewPackage(dir string) (*Package, error) {
pkg := &Package{Dir: dir}
pkg := &Package{Dir: dir, Functions: map[string]*Function{}}
fs, err := os.ReadDir(dir)
if err != nil {
return nil, err
@@ -26,7 +28,14 @@ func NewPackage(dir string) (*Package, error) {
continue
}
pkg.Files = append(pkg.Files, f)
for _, function := range f.Functions {
function := function
key := function.Name
if function.Struct != nil {
key = fmt.Sprintf("%s.%s", function.Struct.Name, key)
}
pkg.Functions[key] = function
}
}
if len(pkg.Files) == 0 {
return nil, errors.New("not found go ext file")
@@ -37,10 +46,11 @@ func NewPackage(dir string) (*Package, error) {
}
type Package struct {
Dir string
Name string
Dirs []string
Files []*File
Dir string
Name string
Dirs []string
Files []*File
Functions map[string]*Function
}
func (p *Package) StructFunc(name string) []*Function {
@@ -92,3 +102,24 @@ func (p *Package) FileComments() *Comment {
}
return comment
}
func (p *Package) GetUnitTest(f *Function) *Function {
if f.Struct == nil {
return p.Functions[fmt.Sprintf("Test%s", str.FirstUpper(f.Name))]
}
return p.Functions[fmt.Sprintf("Test%s_%s", f.Struct.Type.Name, f.Name)]
}
func (p *Package) GetExampleTest(f *Function) *Function {
if f.Struct == nil {
return p.Functions[fmt.Sprintf("Example%s", str.FirstUpper(f.Name))]
}
return p.Functions[fmt.Sprintf("Example%s_%s", f.Struct.Type.Name, f.Name)]
}
func (p *Package) GetBenchmarkTest(f *Function) *Function {
if f.Struct == nil {
return p.Functions[fmt.Sprintf("Benchmark%s", str.FirstUpper(f.Name))]
}
return p.Functions[fmt.Sprintf("Benchmark%s_%s", f.Struct.Type.Name, f.Name)]
}

View File

@@ -17,20 +17,33 @@ func newStruct(astGen *ast.GenDecl) *Struct {
}
}
t, ok := astTypeSpec.Type.(*ast.StructType)
if ok && t.Fields != nil {
for _, field := range t.Fields.List {
s.Fields = append(s.Fields, newField(field)...)
switch ts := astTypeSpec.Type.(type) {
case *ast.StructType:
if ts.Fields != nil {
for _, field := range ts.Fields.List {
s.Fields = append(s.Fields, newField(field)...)
}
}
case *ast.InterfaceType:
s.Interface = true
if ts.Methods != nil {
for _, field := range ts.Methods.List {
s.Fields = append(s.Fields, newField(field)...)
}
}
default:
s.Type = newType(ts)
}
return s
}
type Struct struct {
Name string // 结构体名称
Internal bool // 内部结构体
Comments *Comment // 注释
Generic []*Field // 泛型类型
Fields []*Field // 结构体字段
Test bool // 是否是测试结构体
Name string // 结构体名称
Internal bool // 内部结构体
Interface bool // 接口定义
Comments *Comment // 注释
Generic []*Field // 泛型类型
Fields []*Field // 结构体字段
Type *Type // 和结构体字段二选一,处理类似 type a string 的情况
Test bool // 是否是测试结构体
}

View File

@@ -65,7 +65,13 @@ func newType(expr ast.Expr) *Type {
return "(" + f + ")"
}
return f
}(), handler(e.Results))))
}(), func() string {
f := handler(e.Results)
if e.Results != nil && len(e.Results.List) >= 2 && !strings.HasSuffix(f, "(") {
return "(" + f + ")"
}
return f
}())))
case *ast.InterfaceType:
str.WriteString("interface {")
if e.Methods != nil && len(e.Methods.List) > 0 {

View File

@@ -1,36 +1,40 @@
# Genreadme
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/genreadme)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[New](#New)|暂无描述...
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Builder](#builder)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Builder](#builder)|暂无描述...
</details>
***
## 详情信息
#### func New(pkgDirPath string, output string) *Builder, error
<span id="New"></span>
***
### Builder
### Builder `STRUCT`
```go
type Builder struct {
@@ -40,4 +44,35 @@ type Builder struct {
}
```
#### func (*Builder) Generate() error
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestBuilder_Generate(t *testing.T) {
filepath.Walk("/Users/kercylan/Coding.localized/Go/minotaur", func(path string, info fs.FileInfo, err error) error {
if !info.IsDir() {
return nil
}
if strings.Contains(strings.TrimPrefix(path, "/Users/kercylan/Coding.localized/Go/minotaur"), ".") {
return nil
}
b, err := New(path, filepath.Join(path, "README.md"))
if err != nil {
return nil
}
if err = b.Generate(); err != nil {
panic(err)
}
return nil
})
}
```
</details>
***

View File

@@ -42,31 +42,15 @@ func (b *Builder) Generate() error {
func (b *Builder) genHeader() {
b.title(1, str.FirstUpper(b.p.Name))
b.newLine()
b.newLine(b.p.FileComments().Clear...).newLine()
b.newLine(fmt.Sprintf(`[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/%s)`, b.p.Name))
b.newLine(fmt.Sprintf(`![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)`))
b.newLine().newLine(b.p.FileComments().Clear...).newLine()
b.newLine()
}
func (b *Builder) genMenus() {
b.title(2, "目录")
b.newLine("列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️")
b.detailsStart("展开 / 折叠目录")
b.quote("包级函数定义").newLine()
b.tableCel("函数", "描述")
for _, function := range b.p.PackageFunc() {
if function.Test || function.Internal {
continue
}
b.tableRow(
fmt.Sprintf("[%s](#%s)", function.Name, function.Name),
collection.FindFirstOrDefaultInSlice(function.Comments.Clear, "暂无描述..."),
)
}
b.newLine().newLine()
b.quote("结构体定义").newLine()
b.tableCel("结构体", "描述")
packageFunction := b.p.PackageFunc()
var structList []*astgo.Struct
for _, f := range b.p.Files {
if strings.HasSuffix(f.FilePath, "_test.go") {
continue
@@ -75,16 +59,53 @@ func (b *Builder) genMenus() {
if structInfo.Test || structInfo.Internal {
continue
}
structList = append(structList, structInfo)
}
}
if len(packageFunction)+len(structList) > 0 {
b.title(2, "目录导航")
b.newLine("列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️")
b.detailsStart("展开 / 折叠目录导航")
}
if len(packageFunction) > 0 {
b.quote("包级函数定义").newLine()
b.tableCel("函数名称", "描述")
for _, function := range packageFunction {
if function.Test || function.Internal {
continue
}
b.tableRow(
fmt.Sprintf("[%s](#%s)", function.Name, function.Name),
collection.FindFirstOrDefaultInSlice(function.Comments.Clear, "暂无描述..."),
)
}
b.newLine().newLine()
}
if len(structList) > 0 {
b.quote("类型定义").newLine()
b.tableCel("类型", "名称", "描述")
for _, structInfo := range structList {
if structInfo.Test || structInfo.Internal {
continue
}
b.tableRow(
super.If(structInfo.Interface, "`INTERFACE`", "`STRUCT`"),
fmt.Sprintf("[%s](#%s)", structInfo.Name, strings.ToLower(structInfo.Name)),
collection.FindFirstOrDefaultInSlice(structInfo.Comments.Clear, "暂无描述..."),
)
}
b.detailsEnd()
}
b.detailsEnd()
b.newLine("***")
}
func (b *Builder) genStructs() {
b.title(2, "详情信息")
var funcHandler = func(params []*astgo.Field) string {
var s string
var brackets bool
@@ -122,6 +143,20 @@ func (b *Builder) genStructs() {
for _, comment := range function.Comments.Clear {
b.quote(comment)
}
b.newLine()
if example := b.p.GetExampleTest(function); example != nil {
b.newLine("示例代码:", "```go\n", example.Code(), "```\n")
}
if unitTest := b.p.GetUnitTest(function); unitTest != nil {
b.detailsStart("查看 / 收起单元测试")
b.newLine("```go\n", unitTest.Code(), "```\n")
b.detailsEnd()
}
if benchmarkTest := b.p.GetBenchmarkTest(function); benchmarkTest != nil {
b.detailsStart("查看 / 收起基准测试")
b.newLine("```go\n", benchmarkTest.Code(), "```\n")
b.detailsEnd()
}
b.newLine("***")
}
@@ -130,10 +165,10 @@ func (b *Builder) genStructs() {
if structInfo.Internal || structInfo.Test {
continue
}
b.title(3, structInfo.Name)
b.title(3, fmt.Sprintf("%s `%s`", structInfo.Name, super.If(structInfo.Interface, "INTERFACE", "STRUCT")))
b.newLine(structInfo.Comments.Clear...)
b.newLine("```go")
structDefine := fmt.Sprintf("type %s struct {%s}",
structDefine := fmt.Sprintf("type %s %s",
func() string {
var sb strings.Builder
sb.WriteString(structInfo.Name)
@@ -150,11 +185,27 @@ func (b *Builder) genStructs() {
}(),
func() string {
var sb strings.Builder
if len(structInfo.Fields) > 0 {
sb.WriteString("\n")
}
for _, field := range structInfo.Fields {
sb.WriteString(fmt.Sprintf("\t%s %s\n", field.Name, field.Type.Sign))
if structInfo.Type == nil {
var head = "struct"
if structInfo.Interface {
head = "interface"
}
sb.WriteString(head + " {")
if len(structInfo.Fields) > 0 {
sb.WriteString("\n")
}
if structInfo.Interface {
for _, field := range structInfo.Fields {
sb.WriteString(fmt.Sprintf("\t%s %s\n", field.Name, strings.TrimPrefix(field.Type.Sign, "func")))
}
} else {
for _, field := range structInfo.Fields {
sb.WriteString(fmt.Sprintf("\t%s %s\n", field.Name, field.Type.Sign))
}
}
sb.WriteString("}")
} else {
sb.WriteString(structInfo.Type.Sign)
}
return sb.String()
}())
@@ -183,11 +234,26 @@ func (b *Builder) genStructs() {
}(),
funcHandler(function.Results),
)))
//b.newLine(fmt.Sprintf(`<span id="%s"></span>`, function.Name))
b.quote()
for _, comment := range function.Comments.Clear {
b.quote(comment)
}
if function.Name == "Write" {
fmt.Println()
}
if example := b.p.GetExampleTest(function); example != nil {
b.newLine("示例代码:", "```go\n", example.Code(), "```\n")
}
if unitTest := b.p.GetUnitTest(function); unitTest != nil {
b.detailsStart("查看 / 收起单元测试")
b.newLine("```go\n", unitTest.Code(), "```\n")
b.detailsEnd()
}
if benchmarkTest := b.p.GetBenchmarkTest(function); benchmarkTest != nil {
b.detailsStart("查看 / 收起基准测试")
b.newLine("```go\n", benchmarkTest.Code(), "```\n")
b.detailsEnd()
}
b.newLine("***")
}
}
@@ -243,7 +309,7 @@ func (b *Builder) tableRow(str ...string) *Builder {
}
func (b *Builder) detailsStart(title string) *Builder {
return b.newLine("<details>", "<summary>"+title+"</summary").newLine().newLine()
return b.newLine("<details>", "<summary>"+title+"</summary>").newLine().newLine()
}
func (b *Builder) detailsEnd() *Builder {

View File

@@ -1,134 +1,163 @@
# Generic
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/generic)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
generic 目的在于提供一组基于泛型的用于处理通用功能的函数和数据结构。该包旨在简化通用功能的实现,并提供一致的接口和易于使用的功能。
主要特性:
- 通用功能generic 包支持处理各种通用功能,如数据结构操作、算法实现和常用工具等。您可以使用这些功能来解决各种通用问题,并提高代码的复用性和可维护性。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/generic)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[IsNil](#IsNil)|检查指定的值是否为 nil
|[IsAllNil](#IsAllNil)|检查指定的值是否全部为 nil
|[IsHasNil](#IsHasNil)|检查指定的值是否存在 nil
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[IdR](#idr)|暂无描述...
|[IDR](#idr)|暂无描述...
|[IdW](#idw)|暂无描述...
|[IDW](#idw)|暂无描述...
|[IdR2W](#idr2w)|暂无描述...
|[IDR2W](#idr2w)|暂无描述...
|[Ordered](#ordered)|可排序类型
|[Number](#number)|数字类型
|[SignedNumber](#signednumber)|有符号数字类型
|[Integer](#integer)|整数类型
|[Signed](#signed)|有符号整数类型
|[Unsigned](#unsigned)|无符号整数类型
|[UnsignedNumber](#unsignednumber)|无符号数字类型
|[Float](#float)|浮点类型
|[Basic](#basic)|基本类型
|类型|名称|描述
|:--|:--|:--
|`INTERFACE`|[IdR](#idr)|暂无描述...
|`INTERFACE`|[IDR](#idr)|暂无描述...
|`INTERFACE`|[IdW](#idw)|暂无描述...
|`INTERFACE`|[IDW](#idw)|暂无描述...
|`INTERFACE`|[IdR2W](#idr2w)|暂无描述...
|`INTERFACE`|[IDR2W](#idr2w)|暂无描述...
|`INTERFACE`|[Ordered](#ordered)|可排序类型
|`INTERFACE`|[Number](#number)|数字类型
|`INTERFACE`|[SignedNumber](#signednumber)|有符号数字类型
|`INTERFACE`|[Integer](#integer)|整数类型
|`INTERFACE`|[Signed](#signed)|有符号整数类型
|`INTERFACE`|[Unsigned](#unsigned)|无符号整数类型
|`INTERFACE`|[UnsignedNumber](#unsignednumber)|无符号数字类型
|`INTERFACE`|[Float](#float)|浮点类型
|`INTERFACE`|[Basic](#basic)|基本类型
</details>
***
## 详情信息
#### func IsNil(v V) bool
<span id="IsNil"></span>
> 检查指定的值是否为 nil
***
#### func IsAllNil(v ...V) bool
<span id="IsAllNil"></span>
> 检查指定的值是否全部为 nil
***
#### func IsHasNil(v ...V) bool
<span id="IsHasNil"></span>
> 检查指定的值是否存在 nil
***
### IdR
### IdR `INTERFACE`
```go
type IdR[ID comparable] struct{}
type IdR[ID comparable] interface {
GetId() ID
}
```
### IDR
### IDR `INTERFACE`
```go
type IDR[ID comparable] struct{}
type IDR[ID comparable] interface {
GetID() ID
}
```
### IdW
### IdW `INTERFACE`
```go
type IdW[ID comparable] struct{}
type IdW[ID comparable] interface {
SetId(id ID)
}
```
### IDW
### IDW `INTERFACE`
```go
type IDW[ID comparable] struct{}
type IDW[ID comparable] interface {
SetID(id ID)
}
```
### IdR2W
### IdR2W `INTERFACE`
```go
type IdR2W[ID comparable] struct{}
type IdR2W[ID comparable] interface {
IdR[ID]
IdW[ID]
}
```
### IDR2W
### IDR2W `INTERFACE`
```go
type IDR2W[ID comparable] struct{}
type IDR2W[ID comparable] interface {
IDR[ID]
IDW[ID]
}
```
### Ordered
### Ordered `INTERFACE`
可排序类型
```go
type Ordered struct{}
type Ordered interface {
}
```
### Number
### Number `INTERFACE`
数字类型
```go
type Number struct{}
type Number interface {
}
```
### SignedNumber
### SignedNumber `INTERFACE`
有符号数字类型
```go
type SignedNumber struct{}
type SignedNumber interface {
}
```
### Integer
### Integer `INTERFACE`
整数类型
```go
type Integer struct{}
type Integer interface {
}
```
### Signed
### Signed `INTERFACE`
有符号整数类型
```go
type Signed struct{}
type Signed interface {
}
```
### Unsigned
### Unsigned `INTERFACE`
无符号整数类型
```go
type Unsigned struct{}
type Unsigned interface {
}
```
### UnsignedNumber
### UnsignedNumber `INTERFACE`
无符号数字类型
```go
type UnsignedNumber struct{}
type UnsignedNumber interface {
}
```
### Float
### Float `INTERFACE`
浮点类型
```go
type Float struct{}
type Float interface {
}
```
### Basic
### Basic `INTERFACE`
基本类型
```go
type Basic struct{}
type Basic interface {
}
```

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,8 @@
# Astar
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/astar)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
astar 提供用于实现 A* 算法的函数和数据结构。A* 算法是一种常用的路径搜索算法,用于在图形或网络中找到最短路径。该包旨在简化 A* 算法的实现过程,并提供一致的接口和易于使用的功能。
主要特性:
- 图形表示astar 包支持使用图形或网络来表示路径搜索的环境。您可以定义节点和边,以构建图形,并在其中执行路径搜索。
@@ -7,31 +10,31 @@ astar 提供用于实现 A* 算法的函数和数据结构。A* 算法是一种
- 自定义启发式函数:您可以根据具体问题定义自己的启发式函数,以指导 A* 算法的搜索过程。启发式函数用于估计从当前节点到目标节点的代价,以帮助算法选择最佳路径。
- 可定制性astar 包提供了一些可定制的选项,以满足不同场景下的需求。您可以设置节点的代价、边的权重等参数,以调整算法的行为。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/astar)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[Find](#Find)|使用 A* 算法在导航网格上查找从起点到终点的最短路径,并返回路径上的节点序列。
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Graph](#graph)|适用于 A* 算法的图数据结构接口定义,表示导航网格,其中包含了节点和连接节点的边。
|类型|名称|描述
|:--|:--|:--
|`INTERFACE`|[Graph](#graph)|适用于 A* 算法的图数据结构接口定义,表示导航网格,其中包含了节点和连接节点的边。
</details>
***
## 详情信息
#### func Find(graph Graph[Node], start Node, end Node, cost func (a Node) V, heuristic func (a Node) V) []Node
<span id="Find"></span>
> 使用 A* 算法在导航网格上查找从起点到终点的最短路径,并返回路径上的节点序列。
@@ -54,11 +57,32 @@ astar 提供用于实现 A* 算法的函数和数据结构。A* 算法是一种
> - 函数使用了 A* 算法来搜索最短路径。
> - 函数内部使用了堆数据结构来管理待处理的节点。
> - 函数返回一个节点序列,表示从起点到终点的最短路径。如果找不到路径,则返回空序列。
示例代码:
```go
func ExampleFind() {
graph := Graph{FloorPlan: geometry.FloorPlan{"===========", "X XX X X", "X X XX X", "X XX X", "X XXX X", "X XX X X", "X XX X X", "==========="}}
paths := astar.Find[geometry.Point[int], int](graph, geometry.NewPoint(1, 1), geometry.NewPoint(8, 6), func(a, b geometry.Point[int]) int {
return geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(a, b))
}, func(a, b geometry.Point[int]) int {
return geometry.CalcDistanceWithCoordinate(geometry.DoublePointToCoordinate(a, b))
})
for _, path := range paths {
graph.Put(path, '.')
}
fmt.Println(graph)
}
```
***
### Graph
### Graph `INTERFACE`
适用于 A* 算法的图数据结构接口定义,表示导航网格,其中包含了节点和连接节点的边。
```go
type Graph[Node comparable] struct{}
type Graph[Node comparable] interface {
Neighbours(node Node) []Node
}
```
#### func (Graph) Neighbours(point geometry.Point[int]) []geometry.Point[int]
***

View File

@@ -1,42 +1,75 @@
# Dp
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/dp)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
dp (DistributionPattern) 提供用于在二维数组中根据不同的特征标记为数组成员建立分布链接的函数和数据结构。该包的目标是实现快速查找与给定位置成员具有相同特征且位置紧邻的其他成员。
主要特性:
- 分布链接机制dp 包提供了一种分布链接的机制,可以根据成员的特征将它们链接在一起。这样,可以快速查找与给定成员具有相同特征且位置紧邻的其他成员。
- 二维数组支持:该包支持在二维数组中建立分布链接。可以将二维数组中的成员视为节点,并根据其特征进行链接。
- 快速查找功能:使用 dp 包提供的函数,可以快速查找与给定位置成员具有相同特征且位置紧邻的其他成员。这有助于在二维数组中进行相关性分析或查找相邻成员。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/dp)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewDistributionPattern](#NewDistributionPattern)|构建一个分布图实例
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[DistributionPattern](#distributionpattern)|分布图
|[Link](#link)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[DistributionPattern](#distributionpattern)|分布图
|`STRUCT`|[Link](#link)|暂无描述...
</details>
***
## 详情信息
#### func NewDistributionPattern(sameKindVerifyHandle func (itemA Item) bool) *DistributionPattern[Item]
<span id="NewDistributionPattern"></span>
> 构建一个分布图实例
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewDistributionPattern(t *testing.T) {
dp := NewDistributionPattern[int](func(itemA, itemB int) bool {
return itemA == itemB
})
matrix := []int{1, 1, 2, 2, 2, 2, 1, 2, 2}
dp.LoadMatrixWithPos(3, matrix)
for pos, link := range dp.links {
fmt.Println(pos, link, fmt.Sprintf("%p", link))
}
fmt.Println()
matrix[6] = 2
dp.Refresh(6)
for pos, link := range dp.links {
fmt.Println(pos, link, fmt.Sprintf("%p", link))
}
}
```
</details>
***
### DistributionPattern
### DistributionPattern `STRUCT`
分布图
```go
type DistributionPattern[Item any] struct {
@@ -71,7 +104,7 @@ type DistributionPattern[Item any] struct {
> 通过特定的成员刷新特定位置的分布关系
> - 如果矩阵通过 LoadMatrixWithPos 加载,将会重定向至 Refresh
***
### Link
### Link `STRUCT`
```go
type Link[V any] struct {

View File

@@ -1,39 +1,43 @@
# Matrix
matrix 提供了一个简单的二维数组的实现
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/matrix)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
matrix 提供了一个简单的二维数组的实现
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewMatrix](#NewMatrix)|生成特定宽高的二维矩阵
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Matrix](#matrix)|二维矩阵
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Matrix](#matrix)|二维矩阵
</details>
***
## 详情信息
#### func NewMatrix(width int, height int) *Matrix[T]
<span id="NewMatrix"></span>
> 生成特定宽高的二维矩阵
> - 虽然提供了通过x、y坐标的操作函数但是建议无论如何使用pos进行处理
> - 该矩阵为XY而非YX
***
### Matrix
### Matrix `STRUCT`
二维矩阵
```go
type Matrix[T any] struct {

View File

@@ -1,35 +1,38 @@
# Navmesh
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/navmesh)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
navmesh 提供了用于导航网格处理的函数和数据结构。导航网格是一种常用的数据结构,用于在游戏开发和虚拟环境中进行路径规划和导航。该包旨在简化导航网格的创建、查询和操作过程,并提供高效的导航功能。
主要特性:
- 导航网格表示navmesh 包支持使用导航网格来表示虚拟环境中的可行走区域和障碍物。您可以定义多边形区域和连接关系,以构建导航网格,并在其中执行路径规划和导航。
- 导航算法:采用了 A* 算法作为导航算法,用于在导航网格中找到最短路径或最优路径。这些算法使用启发式函数和代价评估来指导路径搜索,并提供高效的路径规划能力。
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/navmesh)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewNavMesh](#NewNavMesh)|创建一个新的导航网格,并返回一个指向该导航网格的指针。
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[NavMesh](#navmesh)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[NavMesh](#navmesh)|暂无描述...
</details>
***
## 详情信息
#### func NewNavMesh(shapes []geometry.Shape[V], meshShrinkAmount V) *NavMesh[V]
<span id="NewNavMesh"></span>
> 创建一个新的导航网格,并返回一个指向该导航网格的指针。
@@ -49,8 +52,9 @@ navmesh 提供了用于导航网格处理的函数和数据结构。导航网格
>
> 使用建议:
> - 确保 NavMesh 计算精度的情况下V 建议使用 float64 类型
***
### NavMesh
### NavMesh `STRUCT`
```go
type NavMesh[V generic.SignedNumber] struct {
@@ -94,4 +98,32 @@ type NavMesh[V generic.SignedNumber] struct {
> - 如果起点或终点不在任何形状内部,且 NavMesh 的 meshShrinkAmount 大于0则会考虑缩小的形状。
> - 使用 A* 算法在 NavMesh 上搜索从起点形状到终点形状的最短路径。
> - 使用漏斗算法对路径进行优化,以得到最终的路径点序列。
示例代码:
```go
func ExampleNavMesh_FindPath() {
fp := geometry.FloorPlan{"=================================", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "X X", "================================="}
var walkable []geometry.Shape[int]
walkable = append(walkable, geometry.NewShape(geometry.NewPoint(5, 5), geometry.NewPoint(15, 5), geometry.NewPoint(15, 15), geometry.NewPoint(5, 15)), geometry.NewShape(geometry.NewPoint(15, 5), geometry.NewPoint(25, 5), geometry.NewPoint(25, 15), geometry.NewPoint(15, 15)), geometry.NewShape(geometry.NewPoint(15, 15), geometry.NewPoint(25, 15), geometry.NewPoint(25, 25), geometry.NewPoint(15, 25)))
for _, shape := range walkable {
for _, edge := range shape.Edges() {
sx, bx := maths.MinMax(edge.GetStart().GetX(), edge.GetEnd().GetX())
sy, by := maths.MinMax(edge.GetStart().GetY(), edge.GetEnd().GetY())
for x := sx; x <= bx; x++ {
for y := sy; y <= by; y++ {
fp.Put(geometry.NewPoint[int](x, y), '+')
}
}
}
}
nm := navmesh.NewNavMesh(walkable, 0)
path := nm.FindPath(geometry.NewPoint(6, 6), geometry.NewPoint(18, 24))
for _, point := range path {
fp.Put(geometry.NewPoint(point.GetX(), point.GetY()), 'G')
}
fmt.Println(fp)
}
```
***

View File

@@ -1,37 +1,95 @@
# Hub
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/hub)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewObjectPool](#NewObjectPool)|创建一个 ObjectPool
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[ObjectPool](#objectpool)|基于 sync.Pool 实现的线程安全的对象池
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[ObjectPool](#objectpool)|基于 sync.Pool 实现的线程安全的对象池
</details>
***
## 详情信息
#### func NewObjectPool(generator func () *T, releaser func (data *T)) *ObjectPool[*T]
<span id="NewObjectPool"></span>
> 创建一个 ObjectPool
示例代码:
```go
func ExampleNewObjectPool() {
var p = hub.NewObjectPool[map[int]int](func() *map[int]int {
return &map[int]int{}
}, func(data *map[int]int) {
collection.ClearMap(*data)
})
m := *p.Get()
m[1] = 1
p.Release(&m)
fmt.Println(m)
}
```
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewObjectPool(t *testing.T) {
var cases = []struct {
name string
generator func() *map[string]int
releaser func(data *map[string]int)
shouldPanic bool
}{{name: "TestNewObjectPool_NilGenerator", generator: nil, releaser: func(data *map[string]int) {
}, shouldPanic: true}, {name: "TestNewObjectPool_NilReleaser", generator: func() *map[string]int {
return &map[string]int{}
}, releaser: nil, shouldPanic: true}, {name: "TestNewObjectPool_NilGeneratorAndReleaser", generator: nil, releaser: nil, shouldPanic: true}, {name: "TestNewObjectPool_Normal", generator: func() *map[string]int {
return &map[string]int{}
}, releaser: func(data *map[string]int) {
}, shouldPanic: false}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
defer func() {
if err := recover(); c.shouldPanic && err == nil {
t.Error("TestNewObjectPool should panic")
}
}()
_ = hub.NewObjectPool[map[string]int](c.generator, c.releaser)
})
}
}
```
</details>
***
### ObjectPool
### ObjectPool `STRUCT`
基于 sync.Pool 实现的线程安全的对象池
- 一些高频临时生成使用的对象可以通过 ObjectPool 进行管理,例如属性计算等
```go
@@ -42,7 +100,79 @@ type ObjectPool[T any] struct {
```
#### func (*ObjectPool) Get() T
> 获取一个对象
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestObjectPool_Get(t *testing.T) {
var cases = []struct {
name string
generator func() *map[string]int
releaser func(data *map[string]int)
}{{name: "TestObjectPool_Get_Normal", generator: func() *map[string]int {
return &map[string]int{}
}, releaser: func(data *map[string]int) {
for k := range *data {
delete(*data, k)
}
}}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
pool := hub.NewObjectPool[map[string]int](c.generator, c.releaser)
if actual := pool.Get(); len(*actual) != 0 {
t.Error("TestObjectPool_Get failed")
}
})
}
}
```
</details>
***
#### func (*ObjectPool) Release(data T)
> 将使用完成的对象放回缓冲区
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestObjectPool_Release(t *testing.T) {
var cases = []struct {
name string
generator func() *map[string]int
releaser func(data *map[string]int)
}{{name: "TestObjectPool_Release_Normal", generator: func() *map[string]int {
return &map[string]int{}
}, releaser: func(data *map[string]int) {
for k := range *data {
delete(*data, k)
}
}}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
pool := hub.NewObjectPool[map[string]int](c.generator, c.releaser)
msg := pool.Get()
m := *msg
m["test"] = 1
pool.Release(msg)
if len(m) != 0 {
t.Error("TestObjectPool_Release failed")
}
})
}
}
```
</details>
***

View File

@@ -1,19 +1,20 @@
# Huge
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/huge)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewFloat](#NewFloat)|创建一个 Float
|[NewFloatByString](#NewFloatByString)|通过字符串创建一个 Float
@@ -21,38 +22,44 @@
|[NewIntByString](#NewIntByString)|通过字符串创建一个 Int
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Float](#float)|暂无描述...
|[Int](#int)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Float](#float)|暂无描述...
|`STRUCT`|[Int](#int)|暂无描述...
</details>
***
## 详情信息
#### func NewFloat(x T) *Float
<span id="NewFloat"></span>
> 创建一个 Float
***
#### func NewFloatByString(i string) *Float
<span id="NewFloatByString"></span>
> 通过字符串创建一个 Float
> - 如果字符串不是一个合法的数字,则返回 0
***
#### func NewInt(x T) *Int
<span id="NewInt"></span>
> 创建一个 Int
***
#### func NewIntByString(i string) *Int
<span id="NewIntByString"></span>
> 通过字符串创建一个 Int
> - 如果字符串不是一个合法的数字,则返回 0
***
### Float
### Float `STRUCT`
```go
type Float struct{}
type Float big.Float
```
#### func (*Float) Copy() *Float
***
@@ -110,10 +117,10 @@ type Float struct{}
#### func (*Float) IsNegative() bool
> 是否为负数
***
### Int
### Int `STRUCT`
```go
type Int struct{}
type Int big.Int
```
#### func (*Int) Copy() *Int
***

View File

@@ -1,51 +1,67 @@
# Leaderboard
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/leaderboard)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewBinarySearch](#NewBinarySearch)|创建一个基于内存的二分查找排行榜
|[WithBinarySearchCount](#WithBinarySearchCount)|通过限制排行榜竞争者数量来创建排行榜
|[WithBinarySearchASC](#WithBinarySearchASC)|通过升序的方式创建排行榜
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[BinarySearch](#binarysearch)|暂无描述...
|[BinarySearchRankChangeEventHandle](#binarysearchrankchangeeventhandle)|暂无描述...
|[BinarySearchOption](#binarysearchoption)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[BinarySearch](#binarysearch)|暂无描述...
|`STRUCT`|[BinarySearchRankChangeEventHandle](#binarysearchrankchangeeventhandle)|暂无描述...
|`STRUCT`|[BinarySearchOption](#binarysearchoption)|暂无描述...
</details>
***
## 详情信息
#### func NewBinarySearch(options ...BinarySearchOption[CompetitorID, Score]) *BinarySearch[CompetitorID, Score]
<span id="NewBinarySearch"></span>
> 创建一个基于内存的二分查找排行榜
示例代码:
```go
func ExampleNewBinarySearch() {
bs := leaderboard2.NewBinarySearch[string, int](leaderboard2.WithBinarySearchCount[string, int](10))
fmt.Println(bs != nil)
}
```
***
#### func WithBinarySearchCount(rankCount int) BinarySearchOption[CompetitorID, Score]
<span id="WithBinarySearchCount"></span>
> 通过限制排行榜竞争者数量来创建排行榜
> - 默认情况下允许100位竞争者
***
#### func WithBinarySearchASC() BinarySearchOption[CompetitorID, Score]
<span id="WithBinarySearchASC"></span>
> 通过升序的方式创建排行榜
> - 默认情况下为降序
***
### BinarySearch
### BinarySearch `STRUCT`
```go
type BinarySearch[CompetitorID comparable, Score generic.Ordered] struct {
@@ -58,13 +74,13 @@ type BinarySearch[CompetitorID comparable, Score generic.Ordered] struct {
rankClearBeforeEventHandles []BinarySearchRankClearBeforeEventHandle[CompetitorID, Score]
}
```
### BinarySearchRankChangeEventHandle
### BinarySearchRankChangeEventHandle `STRUCT`
```go
type BinarySearchRankChangeEventHandle[CompetitorID comparable, Score generic.Ordered] struct{}
type BinarySearchRankChangeEventHandle[CompetitorID comparable, Score generic.Ordered] func(leaderboard *BinarySearch[CompetitorID, Score], competitorId CompetitorID, oldRank int, oldScore Score)
```
### BinarySearchOption
### BinarySearchOption `STRUCT`
```go
type BinarySearchOption[CompetitorID comparable, Score generic.Ordered] struct{}
type BinarySearchOption[CompetitorID comparable, Score generic.Ordered] func(list *BinarySearch[CompetitorID, Score])
```

View File

@@ -1,19 +1,20 @@
# Log
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/log)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[CallerBasicFormat](#CallerBasicFormat)|返回调用者的基本格式
|[Println](#Println)|暂无描述...
@@ -72,255 +73,339 @@
|[NewOptions](#NewOptions)|创建一个新的日志选项
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Field](#field)|暂无描述...
|[Logger](#logger)|暂无描述...
|[MultiHandler](#multihandler)|暂无描述...
|[Option](#option)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Field](#field)|暂无描述...
|`STRUCT`|[Logger](#logger)|暂无描述...
|`STRUCT`|[MultiHandler](#multihandler)|暂无描述...
|`STRUCT`|[Option](#option)|暂无描述...
</details>
***
## 详情信息
#### func CallerBasicFormat(file string, line int) (repFile string, refLine string)
<span id="CallerBasicFormat"></span>
> 返回调用者的基本格式
***
#### func Println(str string, color string, desc string)
<span id="Println"></span>
***
#### func Default() *Logger
<span id="Default"></span>
> 获取默认的日志记录器
***
#### func SetDefault(l *Logger)
<span id="SetDefault"></span>
> 设置默认的日志记录器
***
#### func SetDefaultBySlog(l *slog.Logger)
<span id="SetDefaultBySlog"></span>
> 设置默认的日志记录器
***
#### func Debug(msg string, args ...any)
<span id="Debug"></span>
> 在 DebugLevel 记录一条消息。该消息包括在日志站点传递的任何字段以及记录器上累积的任何字段
***
#### func Info(msg string, args ...any)
<span id="Info"></span>
> 在 InfoLevel 记录一条消息。该消息包括在日志站点传递的任何字段以及记录器上累积的任何字段
***
#### func Warn(msg string, args ...any)
<span id="Warn"></span>
> 在 WarnLevel 记录一条消息。该消息包括在日志站点传递的任何字段以及记录器上累积的任何字段
***
#### func Error(msg string, args ...any)
<span id="Error"></span>
> 在 ErrorLevel 记录一条消息。该消息包括在日志站点传递的任何字段以及记录器上累积的任何字段
***
#### func DPanic(msg string, args ...any)
<span id="DPanic"></span>
> 在 DPanicLevel 记录一条消息。该消息包括在日志站点传递的任何字段以及记录器上累积的任何字段
> - 如果记录器处于开发模式,它就会出现 panicDPanic 的意思是“development panic”。这对于捕获可恢复但不应该发生的错误很有用
> - 该 panic 仅在 NewHandler 中创建的处理器会生效
***
#### func Panic(msg string, args ...any)
<span id="Panic"></span>
> 在 PanicLevel 记录一条消息。该消息包括在日志站点传递的任何字段以及记录器上累积的任何字段
> - 即使禁用了 PanicLevel 的日志记录,记录器也会出现 panic
***
#### func Fatal(msg string, args ...any)
<span id="Fatal"></span>
> 在 FatalLevel 记录一条消息。该消息包括在日志站点传递的任何字段以及记录器上累积的任何字段
> - 然后记录器调用 os.Exit(1),即使 FatalLevel 的日志记录被禁用
***
#### func Skip(vs ...any) slog.Attr
<span id="Skip"></span>
> 构造一个无操作字段,这在处理其他 Field 构造函数中的无效输入时通常很有用
> - 该函数还支持将其他字段快捷的转换为 Skip 字段
***
#### func Duration(key string, val time.Duration) slog.Attr
<span id="Duration"></span>
> 使用给定的键和值构造一个字段。编码器控制持续时间的序列化方式
***
#### func DurationP(key string, val *time.Duration) slog.Attr
<span id="DurationP"></span>
> 构造一个带有 time.Duration 的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Bool(key string, val bool) slog.Attr
<span id="Bool"></span>
> 构造一个带有布尔值的字段
***
#### func BoolP(key string, val *bool) slog.Attr
<span id="BoolP"></span>
> 构造一个带有布尔值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func String(key string, val string) slog.Attr
<span id="String"></span>
> 构造一个带有字符串值的字段
***
#### func StringP(key string, val *string) slog.Attr
<span id="StringP"></span>
> 构造一个带有字符串值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Int(key string, val I) slog.Attr
<span id="Int"></span>
> 构造一个带有整数值的字段
***
#### func IntP(key string, val *I) slog.Attr
<span id="IntP"></span>
> 构造一个带有整数值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Int8(key string, val I) slog.Attr
<span id="Int8"></span>
> 构造一个带有整数值的字段
***
#### func Int8P(key string, val *I) slog.Attr
<span id="Int8P"></span>
> 构造一个带有整数值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Int16(key string, val I) slog.Attr
<span id="Int16"></span>
> 构造一个带有整数值的字段
***
#### func Int16P(key string, val *I) slog.Attr
<span id="Int16P"></span>
> 构造一个带有整数值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Int32(key string, val I) slog.Attr
<span id="Int32"></span>
> 构造一个带有整数值的字段
***
#### func Int32P(key string, val *I) slog.Attr
<span id="Int32P"></span>
> 构造一个带有整数值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Int64(key string, val I) slog.Attr
<span id="Int64"></span>
> 构造一个带有整数值的字段
***
#### func Int64P(key string, val *I) slog.Attr
<span id="Int64P"></span>
> 构造一个带有整数值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Uint(key string, val I) slog.Attr
<span id="Uint"></span>
> 构造一个带有整数值的字段
***
#### func UintP(key string, val *I) slog.Attr
<span id="UintP"></span>
> 构造一个带有整数值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Uint8(key string, val I) slog.Attr
<span id="Uint8"></span>
> 构造一个带有整数值的字段
***
#### func Uint8P(key string, val *I) slog.Attr
<span id="Uint8P"></span>
> 构造一个带有整数值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Uint16(key string, val I) slog.Attr
<span id="Uint16"></span>
> 构造一个带有整数值的字段
***
#### func Uint16P(key string, val *I) slog.Attr
<span id="Uint16P"></span>
> 构造一个带有整数值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Uint32(key string, val I) slog.Attr
<span id="Uint32"></span>
> 构造一个带有整数值的字段
***
#### func Uint32P(key string, val *I) slog.Attr
<span id="Uint32P"></span>
> 构造一个带有整数值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Uint64(key string, val I) slog.Attr
<span id="Uint64"></span>
> 构造一个带有整数值的字段
***
#### func Uint64P(key string, val *I) slog.Attr
<span id="Uint64P"></span>
> 构造一个带有整数值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Float(key string, val F) slog.Attr
<span id="Float"></span>
> 构造一个带有浮点值的字段
***
#### func FloatP(key string, val *F) slog.Attr
<span id="FloatP"></span>
> 构造一个带有浮点值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Float32(key string, val F) slog.Attr
<span id="Float32"></span>
> 构造一个带有浮点值的字段
***
#### func Float32P(key string, val *F) slog.Attr
<span id="Float32P"></span>
> 构造一个带有浮点值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Float64(key string, val F) slog.Attr
<span id="Float64"></span>
> 构造一个带有浮点值的字段
***
#### func Float64P(key string, val *F) slog.Attr
<span id="Float64P"></span>
> 构造一个带有浮点值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Time(key string, val time.Time) slog.Attr
<span id="Time"></span>
> 构造一个带有时间值的字段
***
#### func TimeP(key string, val *time.Time) slog.Attr
<span id="TimeP"></span>
> 构造一个带有时间值的字段。返回的 Field 将在适当的时候安全且显式地表示 "null"
***
#### func Any(key string, val any) slog.Attr
<span id="Any"></span>
> 构造一个带有任意值的字段
***
#### func Group(key string, args ...any) slog.Attr
<span id="Group"></span>
> 返回分组字段
***
#### func Stack(key string) slog.Attr
<span id="Stack"></span>
> 返回堆栈字段
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestStack(t *testing.T) {
var i int
for {
time.Sleep(time.Second)
Debug("TestStack")
Info("TestStack")
Warn("TestStack")
Error("TestStack")
i++
if i == 3 {
Default().Logger.Handler().(*handler).opts.GerRuntimeHandler().ChangeLevel(slog.LevelInfo)
}
}
}
```
</details>
***
#### func Err(err error) slog.Attr
<span id="Err"></span>
> 构造一个带有错误值的字段
***
#### func NewHandler(w io.Writer, opts *Options) slog.Handler
<span id="NewHandler"></span>
> 创建一个更偏向于人类可读的处理程序,该处理程序也是默认的处理程序
***
#### func NewLogger(handlers ...slog.Handler) *Logger
<span id="NewLogger"></span>
> 创建一个新的日志记录器
***
#### func NewMultiHandler(handlers ...slog.Handler) slog.Handler
<span id="NewMultiHandler"></span>
> 创建一个新的多处理程序
***
#### func NewOptions() *Options
<span id="NewOptions"></span>
> 创建一个新的日志选项
***
### Field
### Field `STRUCT`
```go
type Field struct{}
type Field slog.Attr
```
### Logger
### Logger `STRUCT`
```go
type Logger struct {
*slog.Logger
}
```
### MultiHandler
### MultiHandler `STRUCT`
```go
type MultiHandler struct {
@@ -335,8 +420,8 @@ type MultiHandler struct {
***
#### func (MultiHandler) WithGroup(name string) slog.Handler
***
### Option
### Option `STRUCT`
```go
type Option struct{}
type Option func(opts *Options)
```

View File

@@ -1,19 +1,20 @@
# Survey
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/survey)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewFileFlusher](#NewFileFlusher)|创建一个文件刷新器
|[WithFlushInterval](#WithFlushInterval)|设置日志文件刷新间隔
@@ -27,67 +28,132 @@
|[IncrementAnalyze](#IncrementAnalyze)|增量分析,返回一个函数,每次调用该函数都会分析文件中新增的内容
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Analyzer](#analyzer)|分析器
|[Flusher](#flusher)|用于刷新缓冲区的接口
|[FileFlusher](#fileflusher)|暂无描述...
|[Option](#option)|选项
|[Result](#result)|暂无描述...
|[R](#r)|记录器所记录的一条数据
|[Report](#report)|分析报告
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Analyzer](#analyzer)|分析器
|`INTERFACE`|[Flusher](#flusher)|用于刷新缓冲区的接口
|`STRUCT`|[FileFlusher](#fileflusher)|暂无描述...
|`STRUCT`|[Option](#option)|选项
|`STRUCT`|[Result](#result)|暂无描述...
|`STRUCT`|[R](#r)|记录器所记录的一条数据
|`STRUCT`|[Report](#report)|分析报告
</details>
***
## 详情信息
#### func NewFileFlusher(filePath string, layout ...string) *FileFlusher
<span id="NewFileFlusher"></span>
> 创建一个文件刷新器
> - layout 为日志文件名的时间戳格式 (默认为 time.DateOnly)
***
#### func WithFlushInterval(interval time.Duration) Option
<span id="WithFlushInterval"></span>
> 设置日志文件刷新间隔
> - 默认为 3s当日志文件刷新间隔 <= 0 时,将会在每次写入日志时刷新日志文件
***
#### func Reg(name string, flusher Flusher, options ...Option)
<span id="Reg"></span>
> 注册一个运营日志记录器
***
#### func Record(name string, data map[string]any)
<span id="Record"></span>
> 记录一条运营日志
***
#### func RecordBytes(name string, data []byte)
<span id="RecordBytes"></span>
> 记录一条运营日志
***
#### func Flush(names ...string)
<span id="Flush"></span>
> 将运营日志记录器的缓冲区数据写入到文件
> - name 为空时,将所有记录器的缓冲区数据写入到文件
***
#### func Close(names ...string)
<span id="Close"></span>
> 关闭运营日志记录器
***
#### func Analyze(filePath string, handle func (analyzer *Analyzer, record R)) *Report
<span id="Analyze"></span>
> 分析特定文件的记录,当发生错误时,会发生 panic
> - handle 为并行执行的,需要自行处理并发安全
> - 适用于外部进程对于日志文件的读取,但是需要注意的是,此时日志文件可能正在被写入,所以可能会读取到错误的数据
***
#### func AnalyzeMulti(filePaths []string, handle func (analyzer *Analyzer, record R)) *Report
<span id="AnalyzeMulti"></span>
> 与 Analyze 类似,但是可以分析多个文件
***
#### func IncrementAnalyze(filePath string, handle func (analyzer *Analyzer, record R)) func () *Report, error
#### func IncrementAnalyze(filePath string, handle func (analyzer *Analyzer, record R)) func () ( *Report, error)
<span id="IncrementAnalyze"></span>
> 增量分析,返回一个函数,每次调用该函数都会分析文件中新增的内容
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestIncrementAnalyze(t *testing.T) {
path := `./test/day.2023-09-06.log`
reader := survey.IncrementAnalyze(path, func(analyzer *survey.Analyzer, record survey.R) {
switch record.GetString("type") {
case "open_conn":
analyzer.IncreaseValueNonRepeat("开播人数", record, 1, "live_id")
case "report_rank":
analyzer.IncreaseValue("开始游戏次数", 1)
analyzer.Increase("开播时长", record, "game_time")
analyzer.Sub(record.GetString("live_id")).IncreaseValue("开始游戏次数", 1)
analyzer.Sub(record.GetString("live_id")).Increase("开播时长", record, "game_time")
case "statistics":
analyzer.IncreaseValueNonRepeat("活跃人数", record, 1, "active_player")
analyzer.IncreaseValueNonRepeat("评论人数", record, 1, "comment_player")
analyzer.IncreaseValueNonRepeat("点赞人数", record, 1, "like_player")
analyzer.Sub(record.GetString("live_id")).IncreaseValueNonRepeat("活跃人数", record, 1, "active_player")
analyzer.Sub(record.GetString("live_id")).IncreaseValueNonRepeat("评论人数", record, 1, "comment_player")
analyzer.Sub(record.GetString("live_id")).IncreaseValueNonRepeat("点赞人数", record, 1, "like_player")
giftId := record.GetString("gift.gift_id")
if len(giftId) > 0 {
giftPrice := record.GetFloat64("gift.price")
giftCount := record.GetFloat64("gift.count")
giftSender := record.GetString("gift.gift_senders")
analyzer.IncreaseValue("礼物总价值", giftPrice*giftCount)
analyzer.IncreaseValueNonRepeat(fmt.Sprintf("送礼人数_%s", giftId), record, 1, giftSender)
analyzer.IncreaseValue(fmt.Sprintf("礼物总数_%s", giftId), giftCount)
analyzer.Sub(record.GetString("live_id")).IncreaseValue("礼物总价值", giftPrice*giftCount)
analyzer.Sub(record.GetString("live_id")).IncreaseValueNonRepeat(fmt.Sprintf("送礼人数_%s", giftId), record, 1, giftSender)
analyzer.Sub(record.GetString("live_id")).IncreaseValue(fmt.Sprintf("礼物总数_%s", giftId), giftCount)
}
}
})
for i := 0; i < 10; i++ {
report, err := reader()
if err != nil {
t.Fatal(err)
}
fmt.Println(report.FilterSub("warzone0009"))
}
}
```
</details>
***
### Analyzer
### Analyzer `STRUCT`
分析器
```go
type Analyzer struct {
@@ -148,12 +214,15 @@ type Analyzer struct {
#### func (*Analyzer) GetValueString(key string) string
> 获取当前记录的值
***
### Flusher
### Flusher `INTERFACE`
用于刷新缓冲区的接口
```go
type Flusher struct{}
type Flusher interface {
Flush(records []string)
Info() string
}
```
### FileFlusher
### FileFlusher `STRUCT`
```go
type FileFlusher struct {
@@ -168,20 +237,20 @@ type FileFlusher struct {
***
#### func (*FileFlusher) Info() string
***
### Option
### Option `STRUCT`
选项
```go
type Option struct{}
type Option func(logger *logger)
```
### Result
### Result `STRUCT`
```go
type Result struct{}
type Result gjson.Result
```
### R
### R `STRUCT`
记录器所记录的一条数据
```go
type R struct{}
type R string
```
#### func (R) GetTime(layout string) time.Time
> 获取该记录的时间
@@ -211,7 +280,7 @@ type R struct{}
***
#### func (R) String() string
***
### Report
### Report `STRUCT`
分析报告
```go
type Report struct {

View File

@@ -1,19 +1,20 @@
# Maths
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/maths)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[Compare](#Compare)|根据特定表达式比较两个值
|[IsContinuity](#IsContinuity)|检查一组值是否连续
@@ -40,114 +41,180 @@
|[MakeLastDigitsZero](#MakeLastDigitsZero)|返回一个新的数,其中 num 的最后 digits 位数被设为零。
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[CompareExpression](#compareexpression)|比较表达式
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[CompareExpression](#compareexpression)|比较表达式
</details>
***
## 详情信息
#### func Compare(a V, expression CompareExpression, b V) bool
<span id="Compare"></span>
> 根据特定表达式比较两个值
***
#### func IsContinuity(values S) bool
<span id="IsContinuity"></span>
> 检查一组值是否连续
示例代码:
```go
func ExampleIsContinuity() {
fmt.Println(maths.IsContinuity([]int{1, 2, 3, 4, 5, 6, 7}))
fmt.Println(maths.IsContinuity([]int{1, 2, 3, 5, 5, 6, 7}))
}
```
***
#### func IsContinuityWithSort(values S) bool
<span id="IsContinuityWithSort"></span>
> 检查一组值排序后是否连续
***
#### func GetDefaultTolerance() float64
<span id="GetDefaultTolerance"></span>
> 获取默认误差范围
***
#### func Pow(a int, n int) int
<span id="Pow"></span>
> 整数幂运算
***
#### func PowInt64(a int64, n int64) int64
<span id="PowInt64"></span>
> 整数幂运算
***
#### func Min(a V, b V) V
<span id="Min"></span>
> 返回两个数之中较小的值
***
#### func Max(a V, b V) V
<span id="Max"></span>
> 返回两个数之中较大的值
***
#### func MinMax(a V, b V) (min V, max V)
<span id="MinMax"></span>
> 将两个数按照较小的和较大的顺序进行返回
***
#### func MaxMin(a V, b V) (max V, min V)
<span id="MaxMin"></span>
> 将两个数按照较大的和较小的顺序进行返回
***
#### func Clamp(value V, min V, max V) V
<span id="Clamp"></span>
> 将给定值限制在最小值和最大值之间
***
#### func Tolerance(value1 V, value2 V, tolerance V) bool
<span id="Tolerance"></span>
> 检查两个值是否在一个误差范围内
***
#### func Merge(refer V, a V, b V) V
<span id="Merge"></span>
> 通过一个参考值合并两个数字
***
#### func UnMerge(refer V, num V) (a V, b V)
<span id="UnMerge"></span>
> 通过一个参考值取消合并的两个数字
***
#### func MergeToInt64(v1 V, v2 V) int64
<span id="MergeToInt64"></span>
> 将两个数字合并为一个 int64 数字
***
#### func UnMergeInt64(n int64) V, V
<span id="UnMergeInt64"></span>
> 将一个 int64 数字拆分为两个数字
***
#### func ToContinuous(nums S) map[V]V
<span id="ToContinuous"></span>
> 将一组非连续的数字转换为从1开始的连续数字
> - 返回值是一个 mapkey 是从 1 开始的连续数字value 是原始数字
示例代码:
```go
func ExampleToContinuous() {
var nums = []int{1, 2, 3, 5, 6, 7, 9, 10, 11}
var continuous = maths.ToContinuous(nums)
fmt.Println(nums)
fmt.Println(continuous)
}
```
***
#### func CountDigits(num V) int
<span id="CountDigits"></span>
> 接收一个整数 num 作为输入,并返回该数字的位数
***
#### func GetDigitValue(num int64, digit int) int64
<span id="GetDigitValue"></span>
> 接收一个整数 num 和一个表示目标位数的整数 digit 作为输入,并返
> 回数字 num 在指定位数上的数值。我们使用 math.Abs() 函数获取 num 的绝对值,并通
> 过除以10的操作将 num 移动到目标位数上。然后,通过取余运算得到位数上的数值
***
#### func JoinNumbers(num1 V, n ...V) V
<span id="JoinNumbers"></span>
> 将一组数字连接起来
***
#### func IsOdd(n V) bool
<span id="IsOdd"></span>
> 返回 n 是否为奇数
***
#### func IsEven(n V) bool
<span id="IsEven"></span>
> 返回 n 是否为偶数
***
#### func MakeLastDigitsZero(num T, digits int) T
<span id="MakeLastDigitsZero"></span>
> 返回一个新的数,其中 num 的最后 digits 位数被设为零。
> - 函数首先创建一个 10 的 digits 次方的遮罩,然后通过整除和乘以这个遮罩来使 num 的最后 digits 位归零。
> - 当 T 类型为浮点型时,将被向下取整后再进行转换
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestMakeLastDigitsZero(t *testing.T) {
for i := 0; i < 20; i++ {
n := float64(random.Int64(100, 999999))
t.Log(n, 3, maths.MakeLastDigitsZero(n, 3))
}
}
```
</details>
***
### CompareExpression
### CompareExpression `STRUCT`
比较表达式
```go
type CompareExpression struct{}
type CompareExpression int
```

View File

@@ -1,19 +1,20 @@
# Memory
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/memory)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[Run](#Run)|运行持久化缓存程序
|[BindPersistCacheProgram](#BindPersistCacheProgram)|绑定持久化缓存程序
@@ -21,18 +22,21 @@
|[NewOption](#NewOption)|暂无描述...
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Option](#option)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Option](#option)|暂无描述...
</details>
***
## 详情信息
#### func Run()
<span id="Run"></span>
> 运行持久化缓存程序
***
#### func BindPersistCacheProgram(name string, handler OutputParamHandlerFunc, option ...*Option) func ()
<span id="BindPersistCacheProgram"></span>
@@ -46,6 +50,7 @@
> - 持久化程序处理函数参数类型必须与绑定的缓存程序输出参数类型一致,并且相同 name 的持久化程序必须在 BindAction 之后进行绑定
> - 默认情况下只有执行该函数返回的函数才会进行持久化,如果需要持久化策略,可以设置 option 参数或者自行实现策略调用返回的函数
> - 所有持久化程序绑定完成后,应该主动调用 Run 函数运行
***
#### func BindAction(name string, handler Func) Func
<span id="BindAction"></span>
@@ -60,11 +65,38 @@
>
> 使用场景:
> - 例如在游戏中,需要根据玩家 ID 查询玩家信息,可以使用该函数进行绑定,当查询玩家信息时,如果缓存中存在该玩家信息,将直接返回缓存中的数据,否则将执行 handler 函数进行查询并缓存
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestBindAction(t *testing.T) {
var player *Player
player = QueryPlayer(1)
fmt.Println(player.ID)
player.ID = 666
player = QueryPlayer(1)
fmt.Println(player.ID)
player = QueryPlayer(2)
fmt.Println(player.ID)
QueryPlayerPersist()
time.Sleep(times.Week)
}
```
</details>
***
#### func NewOption() *Option
<span id="NewOption"></span>
***
### Option
### Option `STRUCT`
```go
type Option struct {

View File

@@ -1,19 +1,20 @@
# Moving
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/moving)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewTwoDimensional](#NewTwoDimensional)|创建一个用于2D对象移动的实例(TwoDimensional)
|[WithTwoDimensionalTimeUnit](#WithTwoDimensionalTimeUnit)|通过特定时间单位创建
@@ -22,40 +23,79 @@
|[NewEntity](#NewEntity)|暂无描述...
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[TwoDimensional](#twodimensional)|用于2D对象移动的数据结构
|[TwoDimensionalEntity](#twodimensionalentity)|2D移动对象接口定义
|[Position2DChangeEventHandle](#position2dchangeeventhandle)|暂无描述...
|[TwoDimensionalOption](#twodimensionaloption)|暂无描述...
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[TwoDimensional](#twodimensional)|用于2D对象移动的数据结构
|`INTERFACE`|[TwoDimensionalEntity](#twodimensionalentity)|2D移动对象接口定义
|`STRUCT`|[Position2DChangeEventHandle](#position2dchangeeventhandle)|暂无描述...
|`STRUCT`|[TwoDimensionalOption](#twodimensionaloption)|暂无描述...
</details>
***
## 详情信息
#### func NewTwoDimensional(options ...TwoDimensionalOption[EID, PosType]) *TwoDimensional[EID, PosType]
<span id="NewTwoDimensional"></span>
> 创建一个用于2D对象移动的实例(TwoDimensional)
示例代码:
```go
func ExampleNewTwoDimensional() {
m := moving2.NewTwoDimensional[int64, float64]()
defer func() {
m.Release()
}()
fmt.Println(m != nil)
}
```
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewTwoDimensional(t *testing.T) {
m := moving2.NewTwoDimensional[int64, float64]()
defer func() {
m.Release()
}()
}
```
</details>
***
#### func WithTwoDimensionalTimeUnit(duration time.Duration) TwoDimensionalOption[EID, PosType]
<span id="WithTwoDimensionalTimeUnit"></span>
> 通过特定时间单位创建
> - 默认单位为1毫秒最小单位也为1毫秒
***
#### func WithTwoDimensionalIdleWaitTime(duration time.Duration) TwoDimensionalOption[EID, PosType]
<span id="WithTwoDimensionalIdleWaitTime"></span>
> 通过特定的空闲等待时间创建
> - 默认情况下在没有新的移动计划时将限制 100毫秒 + 移动间隔事件(默认100毫秒)
***
#### func WithTwoDimensionalInterval(duration time.Duration) TwoDimensionalOption[EID, PosType]
<span id="WithTwoDimensionalInterval"></span>
> 通过特定的移动间隔时间创建
***
#### func NewEntity(guid int64, speed float64) *MoveEntity
<span id="NewEntity"></span>
***
### TwoDimensional
### TwoDimensional `STRUCT`
用于2D对象移动的数据结构
- 通过对象调用 MoveTo 方法后将开始执行该对象的移动
- 移动将在根据设置的每次移动间隔时间(WithTwoDimensionalInterval)进行移动,当无对象移动需要移动时将会进入短暂的休眠
@@ -73,18 +113,23 @@ type TwoDimensional[EID generic.Basic, PosType generic.SignedNumber] struct {
position2DStopMoveEventHandles []Position2DStopMoveEventHandle[EID, PosType]
}
```
### TwoDimensionalEntity
### TwoDimensionalEntity `INTERFACE`
2D移动对象接口定义
```go
type TwoDimensionalEntity[EID generic.Basic, PosType generic.SignedNumber] struct{}
type TwoDimensionalEntity[EID generic.Basic, PosType generic.SignedNumber] interface {
GetTwoDimensionalEntityID() EID
GetSpeed() float64
GetPosition() geometry.Point[PosType]
SetPosition(geometry.Point[PosType])
}
```
### Position2DChangeEventHandle
### Position2DChangeEventHandle `STRUCT`
```go
type Position2DChangeEventHandle[EID generic.Basic, PosType generic.SignedNumber] struct{}
type Position2DChangeEventHandle[EID generic.Basic, PosType generic.SignedNumber] func(moving *TwoDimensional[EID, PosType], entity TwoDimensionalEntity[EID, PosType], oldX PosType)
```
### TwoDimensionalOption
### TwoDimensionalOption `STRUCT`
```go
type TwoDimensionalOption[EID generic.Basic, PosType generic.SignedNumber] struct{}
type TwoDimensionalOption[EID generic.Basic, PosType generic.SignedNumber] func(moving *TwoDimensional[EID, PosType])
```

View File

@@ -1,32 +1,28 @@
# Network
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/network)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[IP](#IP)|返回本机出站地址
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息
#### func IP() (ip net.IP, err error)
<span id="IP"></span>
> 返回本机出站地址
***

View File

@@ -1,19 +1,20 @@
# Offset
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/offset)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewTime](#NewTime)|新建一个包含偏移的时间
|[SetGlobal](#SetGlobal)|设置全局偏移时间
@@ -22,36 +23,43 @@
|[Since](#Since)|获取当前时间偏移后的时间自从 t 以来经过的时间
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Time](#time)|带有偏移量的时间
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Time](#time)|带有偏移量的时间
</details>
***
## 详情信息
#### func NewTime(offset time.Duration) *Time
<span id="NewTime"></span>
> 新建一个包含偏移的时间
***
#### func SetGlobal(offset time.Duration)
<span id="SetGlobal"></span>
> 设置全局偏移时间
***
#### func GetGlobal() *Time
<span id="GetGlobal"></span>
> 获取全局偏移时间
***
#### func Now() time.Time
<span id="Now"></span>
> 获取当前时间偏移后的时间
***
#### func Since(t time.Time) time.Duration
<span id="Since"></span>
> 获取当前时间偏移后的时间自从 t 以来经过的时间
***
### Time
### Time `STRUCT`
带有偏移量的时间
```go
type Time struct {

View File

@@ -1,19 +1,20 @@
# Random
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/random)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[Dice](#Dice)|掷骰子
|[DiceN](#DiceN)|掷骰子
@@ -45,129 +46,173 @@
|[WeightMapKey](#WeightMapKey)|按权重随机从map中产生一个数据并返回数据和对应 key
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息
#### func Dice() int
<span id="Dice"></span>
> 掷骰子
> - 常规掷骰子将返回 1-6 的随机数
***
#### func DiceN(n int) int
<span id="DiceN"></span>
> 掷骰子
> - 与 Dice 不同的是,将返回 1-N 的随机数
***
#### func NetIP() net.IP
<span id="NetIP"></span>
> 返回一个随机的IP地址
***
#### func Port() int
<span id="Port"></span>
> 返回一个随机的端口号
***
#### func IPv4() string
<span id="IPv4"></span>
> 返回一个随机产生的IPv4地址。
***
#### func IPv4Port() string
<span id="IPv4Port"></span>
> 返回一个随机产生的IPv4地址和端口。
***
#### func Int64(min int64, max int64) int64
<span id="Int64"></span>
> 返回一个介于min和max之间的int64类型的随机数。
***
#### func Int(min int, max int) int
<span id="Int"></span>
> 返回一个介于min和max之间的的int类型的随机数。
***
#### func Duration(min int64, max int64) time.Duration
<span id="Duration"></span>
> 返回一个介于min和max之间的的Duration类型的随机数。
***
#### func Float64() float64
<span id="Float64"></span>
> 返回一个0~1的浮点数
***
#### func Float32() float32
<span id="Float32"></span>
> 返回一个0~1的浮点数
***
#### func IntN(n int) int
<span id="IntN"></span>
> 返回一个0~n的整数
***
#### func Bool() bool
<span id="Bool"></span>
> 返回一个随机的布尔值
***
#### func ProbabilitySlice(getProbabilityHandle func (data T) float64, data ...T) (hit T, miss bool)
<span id="ProbabilitySlice"></span>
> 按概率随机从切片中产生一个数据并返回命中的对象及是否未命中
> - 当总概率小于 1 将会发生未命中的情况
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestProbabilitySlice(t *testing.T) {
var awards = []int{1, 2, 3, 4, 5, 6, 7}
var probability = []float64{0.1, 2, 0.1, 0.1, 0.1, 0.1, 0.1}
for i := 0; i < 50; i++ {
t.Log(random.ProbabilitySlice(func(data int) float64 {
return probability[data-1]
}, awards...))
}
}
```
</details>
***
#### func ProbabilitySliceIndex(getProbabilityHandle func (data T) float64, data ...T) (hit T, index int, miss bool)
<span id="ProbabilitySliceIndex"></span>
> 按概率随机从切片中产生一个数据并返回命中的对象及对象索引以及是否未命中
> - 当总概率小于 1 将会发生未命中的情况
***
#### func Probability(p int, full ...int) bool
<span id="Probability"></span>
> 输入一个概率,返回是否命中
> - 当 full 不为空时,将以 full 为基数p 为分子,计算命中概率
***
#### func ProbabilityChooseOne(ps ...int) int
<span id="ProbabilityChooseOne"></span>
> 输入一组概率,返回命中的索引
***
#### func RefreshSeed(seed ...int64)
<span id="RefreshSeed"></span>
***
#### func ChineseName() string
<span id="ChineseName"></span>
> 返回一个随机组成的中文姓名。
***
#### func EnglishName() string
<span id="EnglishName"></span>
> 返回一个随机组成的英文姓名。
***
#### func Name() string
<span id="Name"></span>
> 返回一个随机组成的中文或英文姓名
> - 以1/2的概率决定生产的是中文还是英文姓名。
***
#### func NumberString(min int, max int) string
<span id="NumberString"></span>
> 返回一个介于min和max之间的string类型的随机数。
***
#### func NumberStringRepair(min int, max int) string
<span id="NumberStringRepair"></span>
> 返回一个介于min和max之间的string类型的随机数
> - 通过Int64生成一个随机数当结果的字符串长度小于max的字符串长度的情况下使用0在开头补齐。
***
#### func HostName() string
<span id="HostName"></span>
> 返回一个随机产生的hostname。
***
#### func WeightSlice(getWeightHandle func (data T) int64, data ...T) T
<span id="WeightSlice"></span>
> 按权重随机从切片中产生一个数据并返回
***
#### func WeightSliceIndex(getWeightHandle func (data T) int64, data ...T) (item T, index int)
<span id="WeightSliceIndex"></span>
> 按权重随机从切片中产生一个数据并返回数据和对应索引
***
#### func WeightMap(getWeightHandle func (data T) int64, data map[K]T) T
<span id="WeightMap"></span>
> 按权重随机从map中产生一个数据并返回
***
#### func WeightMapKey(getWeightHandle func (data T) int64, data map[K]T) (item T, key K)
<span id="WeightMapKey"></span>
> 按权重随机从map中产生一个数据并返回数据和对应 key
***

View File

@@ -1,19 +1,20 @@
# Reflects
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/reflects)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[WrapperFunc](#WrapperFunc)|包装函数
|[WrapperFuncBefore2After](#WrapperFuncBefore2After)|包装函数,前置函数执行前,后置函数执行后
@@ -25,43 +26,45 @@
|[GetPointer](#GetPointer)|获取指针
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息
#### func WrapperFunc(f any, wrapper func (call func ( []reflect.Value) []reflect.Value) func (args []reflect.Value) []reflect.Value) (wf Func, err error)
<span id="WrapperFunc"></span>
> 包装函数
***
#### func WrapperFuncBefore2After(f Func, before func (), after func ()) (wf Func, err error)
<span id="WrapperFuncBefore2After"></span>
> 包装函数,前置函数执行前,后置函数执行后
***
#### func WrapperFuncBefore(f Func, before func ()) (wf Func, err error)
<span id="WrapperFuncBefore"></span>
> 包装函数,前置函数执行前
***
#### func WrapperFuncAfter(f Func, after func ()) (wf Func, err error)
<span id="WrapperFuncAfter"></span>
> 包装函数,后置函数执行后
***
#### func GetPtrUnExportFiled(s reflect.Value, filedIndex int) reflect.Value
<span id="GetPtrUnExportFiled"></span>
> 获取指针类型的未导出字段
***
#### func SetPtrUnExportFiled(s reflect.Value, filedIndex int, val reflect.Value)
<span id="SetPtrUnExportFiled"></span>
> 设置指针类型的未导出字段
***
#### func Copy(s reflect.Value) reflect.Value
<span id="Copy"></span>
> 拷贝
***
#### func GetPointer(src T) reflect.Value
<span id="GetPointer"></span>
> 获取指针
***

View File

@@ -1,19 +1,20 @@
# Runtimes
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/runtimes)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[GetWorkingDir](#GetWorkingDir)|获取工作目录绝对路径
|[GetTempDir](#GetTempDir)|获取系统临时目录
@@ -22,31 +23,30 @@
|[CurrentRunningFuncName](#CurrentRunningFuncName)|获取正在运行的函数名
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息
#### func GetWorkingDir() string
<span id="GetWorkingDir"></span>
> 获取工作目录绝对路径
***
#### func GetTempDir() string
<span id="GetTempDir"></span>
> 获取系统临时目录
***
#### func GetExecutablePathByBuild() string
<span id="GetExecutablePathByBuild"></span>
> 获取当前执行文件绝对路径go build
***
#### func GetExecutablePathByCaller() string
<span id="GetExecutablePathByCaller"></span>
> 获取当前执行文件绝对路径go run
***
#### func CurrentRunningFuncName(skip ...int) string
<span id="CurrentRunningFuncName"></span>
> 获取正在运行的函数名
***

View File

@@ -1,19 +1,20 @@
# Sole
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/sole)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[RegNameSpace](#RegNameSpace)|注册特定命名空间的唯一标识符
|[UnRegNameSpace](#UnRegNameSpace)|解除注销特定命名空间的唯一标识符
@@ -33,80 +34,98 @@
|[AutoIncrementString](#AutoIncrementString)|获取一个自增的字符串
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[Once](#once)|用于数据取值去重的结构体
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[Once](#once)|用于数据取值去重的结构体
</details>
***
## 详情信息
#### func RegNameSpace(name any)
<span id="RegNameSpace"></span>
> 注册特定命名空间的唯一标识符
***
#### func UnRegNameSpace(name any)
<span id="UnRegNameSpace"></span>
> 解除注销特定命名空间的唯一标识符
***
#### func Get() int64
<span id="Get"></span>
> 获取全局唯一标识符
***
#### func Reset()
<span id="Reset"></span>
> 重置全局唯一标识符
***
#### func GetWith(name any) int64
<span id="GetWith"></span>
> 获取特定命名空间的唯一标识符
***
#### func ResetWith(name any)
<span id="ResetWith"></span>
> 重置特定命名空间的唯一标识符
***
#### func NewOnce() *Once[V]
<span id="NewOnce"></span>
> 创建一个用于数据取值去重的结构实例
***
#### func SonyflakeIDE() int64, error
<span id="SonyflakeIDE"></span>
> 获取一个雪花id
***
#### func SonyflakeID() int64
<span id="SonyflakeID"></span>
> 获取一个雪花id
***
#### func SonyflakeSetting(settings sonyflake.Settings)
<span id="SonyflakeSetting"></span>
> 配置雪花id生成策略
***
#### func AutoIncrementUint32() uint32
<span id="AutoIncrementUint32"></span>
> 获取一个自增的 uint32 值
***
#### func AutoIncrementUint64() uint64
<span id="AutoIncrementUint64"></span>
> 获取一个自增的 uint64 值
***
#### func AutoIncrementInt32() int32
<span id="AutoIncrementInt32"></span>
> 获取一个自增的 int32 值
***
#### func AutoIncrementInt64() int64
<span id="AutoIncrementInt64"></span>
> 获取一个自增的 int64 值
***
#### func AutoIncrementInt() int
<span id="AutoIncrementInt"></span>
> 获取一个自增的 int 值
***
#### func AutoIncrementString() string
<span id="AutoIncrementString"></span>
> 获取一个自增的字符串
***
### Once
### Once `STRUCT`
用于数据取值去重的结构体
```go
type Once[V any] struct {

View File

@@ -1,31 +1,26 @@
# Sorts
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/sorts)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[Topological](#Topological)|拓扑排序是一种对有向图进行排序的算法,它可以用来解决一些依赖关系的问题,比如计算字段的依赖关系。拓扑排序会将存在依赖关系的元素进行排序,使得依赖关系的元素总是排在被依赖的元素之前。
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息
#### func Topological(slice S, queryIndexHandler func (item V) Index, queryDependsHandler func (item V) []Index) S, error
<span id="Topological"></span>
> 拓扑排序是一种对有向图进行排序的算法,它可以用来解决一些依赖关系的问题,比如计算字段的依赖关系。拓扑排序会将存在依赖关系的元素进行排序,使得依赖关系的元素总是排在被依赖的元素之前。
@@ -34,4 +29,93 @@
> - queryDependsHandler: 用于查询切片中每个元素的依赖关系,返回的是一个索引切片,如果没有依赖关系,那么返回空切片
>
> 该函数在存在循环依赖的情况下将会返回 ErrCircularDependencyDetected 错误
示例代码:
```go
func ExampleTopological() {
type Item struct {
ID int
Depends []int
}
var items = []Item{{ID: 2, Depends: []int{4}}, {ID: 1, Depends: []int{2, 3}}, {ID: 3, Depends: []int{4}}, {ID: 4, Depends: []int{5}}, {ID: 5, Depends: []int{}}}
var sorted, err = sorts.Topological(items, func(item Item) int {
return item.ID
}, func(item Item) []int {
return item.Depends
})
if err != nil {
return
}
for _, item := range sorted {
fmt.Println(item.ID, "|", item.Depends)
}
}
```
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestTopological(t *testing.T) {
type Item struct {
ID int
Depends []int
}
var items = []Item{{ID: 2, Depends: []int{4}}, {ID: 1, Depends: []int{2, 3}}, {ID: 3, Depends: []int{4}}, {ID: 4, Depends: []int{5}}, {ID: 5, Depends: []int{}}}
var sorted, err = sorts.Topological(items, func(item Item) int {
return item.ID
}, func(item Item) []int {
return item.Depends
})
if err != nil {
t.Error(err)
return
}
for _, item := range sorted {
t.Log(item.ID, "|", item.Depends)
}
}
```
</details>
<details>
<summary>查看 / 收起基准测试</summary>
```go
func BenchmarkTopological(b *testing.B) {
type Item struct {
ID int
Depends []int
}
var items = []Item{{ID: 2, Depends: []int{4}}, {ID: 1, Depends: []int{2, 3}}, {ID: 3, Depends: []int{4}}, {ID: 4, Depends: []int{5}}, {ID: 5, Depends: []int{}}}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := Topological(items, func(item Item) int {
return item.ID
}, func(item Item) []int {
return item.Depends
})
if err != nil {
b.Error(err)
return
}
}
}
```
</details>
***

View File

@@ -1,19 +1,20 @@
# Str
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/str)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[RangeLine](#RangeLine)|对传入的eachString进行按行切片后再进行遍历
|[SplitTrimSpace](#SplitTrimSpace)|按照空格分割字符串并去除空格
@@ -39,91 +40,103 @@
|[FormatSpeedyFloat64](#FormatSpeedyFloat64)|返回numberStr经过格式化后去除空格和“,”分隔符的结果
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息
#### func RangeLine(eachString string, eachFunc func (index int, line string) error) error
<span id="RangeLine"></span>
> 对传入的eachString进行按行切片后再进行遍历
> - 该函数会预先对“\r\n”进行处理替换为“\n”。
> - 在遍历到每一行的时候会将结果index和line作为入参传入eachFunc中进行调用。
> - index表示了当前行的行号由0开始line表示了当前行的内容。
***
#### func SplitTrimSpace(str string, sep string) []string
<span id="SplitTrimSpace"></span>
> 按照空格分割字符串并去除空格
***
#### func FirstUpper(str string) string
<span id="FirstUpper"></span>
> 首字母大写
***
#### func FirstLower(str string) string
<span id="FirstLower"></span>
> 首字母小写
***
#### func FirstUpperBytes(str []byte) []byte
<span id="FirstUpperBytes"></span>
> 首字母大写
***
#### func FirstLowerBytes(str []byte) []byte
<span id="FirstLowerBytes"></span>
> 首字母小写
***
#### func IsEmpty(str string) bool
<span id="IsEmpty"></span>
> 判断字符串是否为空
***
#### func IsEmptyBytes(str []byte) bool
<span id="IsEmptyBytes"></span>
> 判断字符串是否为空
***
#### func IsNotEmpty(str string) bool
<span id="IsNotEmpty"></span>
> 判断字符串是否不为空
***
#### func IsNotEmptyBytes(str []byte) bool
<span id="IsNotEmptyBytes"></span>
> 判断字符串是否不为空
***
#### func SnakeString(str string) string
<span id="SnakeString"></span>
> 蛇形字符串
***
#### func SnakeStringBytes(str []byte) []byte
<span id="SnakeStringBytes"></span>
> 蛇形字符串
***
#### func CamelString(str string) string
<span id="CamelString"></span>
> 驼峰字符串
***
#### func CamelStringBytes(str []byte) []byte
<span id="CamelStringBytes"></span>
> 驼峰字符串
***
#### func SortJoin(delimiter string, s ...string) string
<span id="SortJoin"></span>
> 将多个字符串排序后拼接
***
#### func HideSensitivity(str string) (result string)
<span id="HideSensitivity"></span>
> 返回防敏感化后的字符串
> - 隐藏身份证、邮箱、手机号等敏感信息用*号替代
***
#### func ThousandsSeparator(str string) string
<span id="ThousandsSeparator"></span>
> 返回将str进行千位分隔符处理后的字符串。
***
#### func KV(str string, tag ...string) string, string
<span id="KV"></span>
> 返回str经过转换后形成的key、value
> - 这里tag表示使用什么字符串来区分key和value的分隔符。
> - 默认情况即不传入tag的情况下分隔符为“=”。
***
#### func FormatSpeedyInt(numberStr string) int, error
<span id="FormatSpeedyInt"></span>
@@ -131,6 +144,7 @@
> - 当字符串为“123,456,789”的时候返回结果为“123456789”。
> - 当字符串为“123 456 789”的时候返回结果为“123456789”。
> - 当字符串为“1 23, 45 6, 789”的时候返回结果为“123456789”。
***
#### func FormatSpeedyInt64(numberStr string) int64, error
<span id="FormatSpeedyInt64"></span>
@@ -138,6 +152,7 @@
> - 当字符串为“123,456,789”的时候返回结果为“123456789”。
> - 当字符串为“123 456 789”的时候返回结果为“123456789”。
> - 当字符串为“1 23, 45 6, 789”的时候返回结果为“123456789”。
***
#### func FormatSpeedyFloat32(numberStr string) float64, error
<span id="FormatSpeedyFloat32"></span>
@@ -145,6 +160,7 @@
> - 当字符串为“123,456,789.123”的时候返回结果为“123456789.123”。
> - 当字符串为“123 456 789.123”的时候返回结果为“123456789.123”。
> - 当字符串为“1 23, 45 6, 789.123”的时候返回结果为“123456789.123”。
***
#### func FormatSpeedyFloat64(numberStr string) float64, error
<span id="FormatSpeedyFloat64"></span>
@@ -152,4 +168,5 @@
> - 当字符串为“123,456,789.123”的时候返回结果为“123456789.123”。
> - 当字符串为“123 456 789.123”的时候返回结果为“123456789.123”。
> - 当字符串为“1 23, 45 6, 789.123”的时候返回结果为“123456789.123”。
***

View File

@@ -1,19 +1,20 @@
# Super
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/super)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[NewBitSet](#NewBitSet)|通过指定的 Bit 位创建一个 BitSet
|[TryWriteChannel](#TryWriteChannel)|尝试写入 channel如果 channel 无法写入则忽略,返回是否写入成功
@@ -87,249 +88,417 @@
|[CompareVersion](#CompareVersion)|返回一个整数,用于表示两个版本号的比较结果:
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[BitSet](#bitset)|是一个可以动态增长的比特位集合
|[LossCounter](#losscounter)|暂无描述...
|[Matcher](#matcher)|匹配器
|[Permission](#permission)|暂无描述...
|[StackGo](#stackgo)|用于获取上一个协程调用的堆栈信息
|[VerifyHandle](#verifyhandle)|校验句柄
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[BitSet](#bitset)|是一个可以动态增长的比特位集合
|`STRUCT`|[LossCounter](#losscounter)|暂无描述...
|`STRUCT`|[Matcher](#matcher)|匹配器
|`STRUCT`|[Permission](#permission)|暂无描述...
|`STRUCT`|[StackGo](#stackgo)|用于获取上一个协程调用的堆栈信息
|`STRUCT`|[VerifyHandle](#verifyhandle)|校验句柄
</details>
***
## 详情信息
#### func NewBitSet(bits ...Bit) *BitSet[Bit]
<span id="NewBitSet"></span>
> 通过指定的 Bit 位创建一个 BitSet
***
#### func TryWriteChannel(ch chan T, data T) bool
<span id="TryWriteChannel"></span>
> 尝试写入 channel如果 channel 无法写入则忽略,返回是否写入成功
> - 无法写入的情况包括channel 已满、channel 已关闭
***
#### func TryWriteChannelByHandler(ch chan T, data T, handler func ())
<span id="TryWriteChannelByHandler"></span>
> 尝试写入 channel如果 channel 无法写入则执行 handler
> - 无法写入的情况包括channel 已满、channel 已关闭
***
#### func RegError(code int, message string) error
<span id="RegError"></span>
> 通过错误码注册错误,返回错误的引用
***
#### func RegErrorRef(code int, message string, ref error) error
<span id="RegErrorRef"></span>
> 通过错误码注册错误,返回错误的引用
> - 引用将会被重定向到注册的错误信息
***
#### func GetError(err error) int, error
<span id="GetError"></span>
> 通过错误引用获取错误码和真实错误信息,如果错误不存在则返回 0如果错误引用不存在则返回原本的错误
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestGetError(t *testing.T) {
var ErrNotFound = errors.New("not found")
var _ = super.RegErrorRef(100, "test error", ErrNotFound)
t.Log(super.GetError(ErrNotFound))
}
```
</details>
***
#### func RecoverTransform(a any) error
<span id="RecoverTransform"></span>
> recover 错误转换
示例代码:
```go
func ExampleRecoverTransform() {
defer func() {
if err := super.RecoverTransform(recover()); err != nil {
fmt.Println(err)
}
}()
panic("test")
}
```
***
#### func Handle(f func ())
<span id="Handle"></span>
> 执行 f 函数,如果 f 为 nil则不执行
***
#### func HandleErr(f func () error) error
<span id="HandleErr"></span>
> 执行 f 函数,如果 f 为 nil则不执行
***
#### func HandleV(v V, f func (v V))
<span id="HandleV"></span>
> 执行 f 函数,如果 f 为 nil则不执行
***
#### func GoFormat(filePath string)
<span id="GoFormat"></span>
> go 代码格式化
***
#### func If(expression bool, t T, f T) T
<span id="If"></span>
***
#### func MarshalJSON(v interface {}) []byte
<span id="MarshalJSON"></span>
> 将对象转换为 json
> - 当转换失败时,将返回 json 格式的空对象
***
#### func MarshalJSONE(v interface {}) []byte, error
<span id="MarshalJSONE"></span>
> 将对象转换为 json
> - 当转换失败时,将返回错误信息
***
#### func UnmarshalJSON(data []byte, v interface {}) error
<span id="UnmarshalJSON"></span>
> 将 json 转换为对象
***
#### func MarshalIndentJSON(v interface {}, prefix string, indent string) []byte
<span id="MarshalIndentJSON"></span>
> 将对象转换为 json
***
#### func MarshalToTargetWithJSON(src interface {}, dest interface {}) error
<span id="MarshalToTargetWithJSON"></span>
> 将对象转换为目标对象
***
#### func StartLossCounter() *LossCounter
<span id="StartLossCounter"></span>
> 开始损耗计数
***
#### func Match(value Value) *Matcher[Value, Result]
<span id="Match"></span>
> 匹配
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestMatch(t *testing.T) {
Convey("TestMatch", t, func() {
So(super.Match[int, string](1).Case(1, "a").Case(2, "b").Default("c"), ShouldEqual, "a")
So(super.Match[int, string](2).Case(1, "a").Case(2, "b").Default("c"), ShouldEqual, "b")
So(super.Match[int, string](3).Case(1, "a").Case(2, "b").Default("c"), ShouldEqual, "c")
})
}
```
</details>
***
#### func IsNumber(v any) bool
<span id="IsNumber"></span>
> 判断是否为数字
***
#### func NumberToRome(num int) string
<span id="NumberToRome"></span>
> 将数字转换为罗马数字
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNumberToRome(t *testing.T) {
tests := []struct {
input int
output string
}{{input: 1, output: "I"}, {input: 5, output: "V"}, {input: 10, output: "X"}, {input: 50, output: "L"}, {input: 100, output: "C"}, {input: 500, output: "D"}, {input: 1000, output: "M"}}
for _, test := range tests {
result := super.NumberToRome(test.input)
if result != test.output {
t.Errorf("NumberToRome(%d) = %s; want %s", test.input, result, test.output)
}
}
}
```
</details>
***
#### func StringToInt(value string) int
<span id="StringToInt"></span>
> 字符串转换为整数
***
#### func StringToFloat64(value string) float64
<span id="StringToFloat64"></span>
> 字符串转换为 float64
***
#### func StringToBool(value string) bool
<span id="StringToBool"></span>
> 字符串转换为 bool
***
#### func StringToUint64(value string) uint64
<span id="StringToUint64"></span>
> 字符串转换为 uint64
***
#### func StringToUint(value string) uint
<span id="StringToUint"></span>
> 字符串转换为 uint
***
#### func StringToFloat32(value string) float32
<span id="StringToFloat32"></span>
> 字符串转换为 float32
***
#### func StringToInt64(value string) int64
<span id="StringToInt64"></span>
> 字符串转换为 int64
***
#### func StringToUint32(value string) uint32
<span id="StringToUint32"></span>
> 字符串转换为 uint32
***
#### func StringToInt32(value string) int32
<span id="StringToInt32"></span>
> 字符串转换为 int32
***
#### func StringToUint16(value string) uint16
<span id="StringToUint16"></span>
> 字符串转换为 uint16
***
#### func StringToInt16(value string) int16
<span id="StringToInt16"></span>
> 字符串转换为 int16
***
#### func StringToUint8(value string) uint8
<span id="StringToUint8"></span>
> 字符串转换为 uint8
***
#### func StringToInt8(value string) int8
<span id="StringToInt8"></span>
> 字符串转换为 int8
***
#### func StringToByte(value string) byte
<span id="StringToByte"></span>
> 字符串转换为 byte
***
#### func StringToRune(value string) rune
<span id="StringToRune"></span>
> 字符串转换为 rune
***
#### func IntToString(value int) string
<span id="IntToString"></span>
> 整数转换为字符串
***
#### func Float64ToString(value float64) string
<span id="Float64ToString"></span>
> float64 转换为字符串
***
#### func BoolToString(value bool) string
<span id="BoolToString"></span>
> bool 转换为字符串
***
#### func Uint64ToString(value uint64) string
<span id="Uint64ToString"></span>
> uint64 转换为字符串
***
#### func UintToString(value uint) string
<span id="UintToString"></span>
> uint 转换为字符串
***
#### func Float32ToString(value float32) string
<span id="Float32ToString"></span>
> float32 转换为字符串
***
#### func Int64ToString(value int64) string
<span id="Int64ToString"></span>
> int64 转换为字符串
***
#### func Uint32ToString(value uint32) string
<span id="Uint32ToString"></span>
> uint32 转换为字符串
***
#### func Int32ToString(value int32) string
<span id="Int32ToString"></span>
> int32 转换为字符串
***
#### func Uint16ToString(value uint16) string
<span id="Uint16ToString"></span>
> uint16 转换为字符串
***
#### func Int16ToString(value int16) string
<span id="Int16ToString"></span>
> int16 转换为字符串
***
#### func Uint8ToString(value uint8) string
<span id="Uint8ToString"></span>
> uint8 转换为字符串
***
#### func Int8ToString(value int8) string
<span id="Int8ToString"></span>
> int8 转换为字符串
***
#### func ByteToString(value byte) string
<span id="ByteToString"></span>
> byte 转换为字符串
***
#### func RuneToString(value rune) string
<span id="RuneToString"></span>
> rune 转换为字符串
***
#### func StringToSlice(value string) []string
<span id="StringToSlice"></span>
> 字符串转换为切片
***
#### func SliceToString(value []string) string
<span id="SliceToString"></span>
> 切片转换为字符串
***
#### func NewPermission() *Permission[Code, EntityID]
<span id="NewPermission"></span>
> 创建权限
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewPermission(t *testing.T) {
const (
Read = 1 << iota
Write
Execute
)
p := super.NewPermission[int, int]()
p.AddPermission(1, Read, Write)
t.Log(p.HasPermission(1, Read))
t.Log(p.HasPermission(1, Write))
p.SetPermission(2, Read|Write)
t.Log(p.HasPermission(2, Read))
t.Log(p.HasPermission(2, Execute))
p.SetPermission(2, Execute)
t.Log(p.HasPermission(2, Execute))
t.Log(p.HasPermission(2, Read))
t.Log(p.HasPermission(2, Write))
p.RemovePermission(2, Execute)
t.Log(p.HasPermission(2, Execute))
}
```
</details>
***
#### func Retry(count int, interval time.Duration, f func () error) error
<span id="Retry"></span>
> 根据提供的 count 次数尝试执行 f 函数,如果 f 函数返回错误,则在 interval 后重试,直到成功或者达到 count 次数
***
#### func RetryByRule(f func () error, rule func (count int) time.Duration) error
<span id="RetryByRule"></span>
> 根据提供的规则尝试执行 f 函数,如果 f 函数返回错误,则根据 rule 的返回值进行重试
> - rule 将包含一个入参,表示第几次重试,返回值表示下一次重试的时间间隔,当返回值为 0 时,表示不再重试
> - rule 的 count 将在 f 首次失败后变为 1因此 rule 的入参将从 1 开始
***
#### func RetryByExponentialBackoff(f func () error, maxRetries int, baseDelay time.Duration, maxDelay time.Duration, multiplier float64, randomization float64, ignoreErrors ...error) error
<span id="RetryByExponentialBackoff"></span>
@@ -340,6 +509,7 @@
> - multiplier延迟时间的乘数通常为 2
> - randomization延迟时间的随机化因子通常为 0.5
> - ignoreErrors忽略的错误当 f 返回的错误在 ignoreErrors 中时,将不会进行重试
***
#### func ConditionalRetryByExponentialBackoff(f func () error, cond func () bool, maxRetries int, baseDelay time.Duration, maxDelay time.Duration, multiplier float64, randomization float64, ignoreErrors ...error) error
<span id="ConditionalRetryByExponentialBackoff"></span>
@@ -348,54 +518,164 @@
>
> 该函数通常用于在重试过程中,需要中断重试的场景,例如:
> - 用户请求开始游戏,由于网络等情况,进入重试状态。此时用户再次发送开始游戏请求,此时需要中断之前的重试,避免重复进入游戏
***
#### func RetryAsync(count int, interval time.Duration, f func () error, callback func (err error))
<span id="RetryAsync"></span>
> 与 Retry 类似,但是是异步执行
> - 传入的 callback 函数会在执行完毕后被调用,如果执行成功,则 err 为 nil否则为错误信息
> - 如果 callback 为 nil则不会在执行完毕后被调用
***
#### func RetryForever(interval time.Duration, f func () error)
<span id="RetryForever"></span>
> 根据提供的 interval 时间间隔尝试执行 f 函数,如果 f 函数返回错误,则在 interval 后重试,直到成功
***
#### func NewStackGo() *StackGo
<span id="NewStackGo"></span>
> 返回一个用于获取上一个协程调用的堆栈信息的收集器
***
#### func LaunchTime() time.Time
<span id="LaunchTime"></span>
> 获取程序启动时间
***
#### func Hostname() string
<span id="Hostname"></span>
> 获取主机名
***
#### func PID() int
<span id="PID"></span>
> 获取进程 PID
***
#### func StringToBytes(s string) []byte
<span id="StringToBytes"></span>
> 以零拷贝的方式将字符串转换为字节切片
***
#### func BytesToString(b []byte) string
<span id="BytesToString"></span>
> 以零拷贝的方式将字节切片转换为字符串
***
#### func Convert(src A) B
<span id="Convert"></span>
> 以零拷贝的方式将一个对象转换为另一个对象
> - 两个对象字段必须完全一致
> - 该函数可以绕过私有字段的访问限制
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestConvert(t *testing.T) {
type B struct {
nocmp [0]func()
v atomic.Value
}
var a = atomic.NewString("hello")
var b = super.Convert[*atomic.String, *B](a)
fmt.Println(b.v.Load())
}
```
</details>
***
#### func Verify(handle func ( V)) *VerifyHandle[V]
<span id="Verify"></span>
> 对特定表达式进行校验,当表达式不成立时,将执行 handle
示例代码:
```go
func ExampleVerify() {
var getId = func() int {
return 1
}
var n *super.VerifyHandle[int]
super.Verify(func(err error) {
fmt.Println(err)
}).Case(getId() == 1, errors.New("id can't be 1")).Do()
super.Verify(func(err error) {
fmt.Println(err)
}).PreCase(func() bool {
return n == nil
}, errors.New("n can't be nil"), func(verify *super.VerifyHandle[error]) bool {
return verify.Do()
})
}
```
***
#### func OldVersion(version1 string, version2 string) bool
<span id="OldVersion"></span>
> 检查 version2 对于 version1 来说是不是旧版本
示例代码:
```go
func ExampleOldVersion() {
result := super.OldVersion("1.2.3", "1.2.2")
fmt.Println(result)
}
```
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestOldVersion(t *testing.T) {
testCases := []struct {
version1 string
version2 string
want bool
}{{"1.2.3", "1.2.2", true}, {"1.2.1", "1.2.2", false}, {"1.2.3", "1.2.3", false}, {"v1.2.3", "v1.2.2", true}, {"v1.2.3", "v1.2.4", false}, {"v1.2.3", "1.2.3", false}, {"vxx2faf.d2ad5.dd3", "gga2faf.d2ad5.dd2", true}, {"awd2faf.d2ad4.dd3", "vsd2faf.d2ad5.dd3", false}, {"vxd2faf.d2ad5.dd3", "qdq2faf.d2ad5.dd3", false}, {"1.2.3", "vdafe2faf.d2ad5.dd3", false}, {"v1.2.3", "vdafe2faf.d2ad5.dd3", false}}
for _, tc := range testCases {
got := super.OldVersion(tc.version1, tc.version2)
if got != tc.want {
t.Errorf("OldVersion(%q, %q) = %v; want %v", tc.version1, tc.version2, got, tc.want)
}
}
}
```
</details>
<details>
<summary>查看 / 收起基准测试</summary>
```go
func BenchmarkOldVersion(b *testing.B) {
for i := 0; i < b.N; i++ {
super.OldVersion("vfe2faf.d2ad5.dd3", "vda2faf.d2ad5.dd2")
}
}
```
</details>
***
#### func CompareVersion(version1 string, version2 string) int
<span id="CompareVersion"></span>
@@ -403,8 +683,63 @@
> - 如果 version1 大于 version2它将返回 1
> - 如果 version1 小于 version2它将返回 -1
> - 如果 version1 和 version2 相等,它将返回 0
示例代码:
```go
func ExampleCompareVersion() {
result := super.CompareVersion("1.2.3", "1.2.2")
fmt.Println(result)
}
```
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestCompareVersion(t *testing.T) {
testCases := []struct {
version1 string
version2 string
want int
}{{"1.2.3", "1.2.2", 1}, {"1.2.1", "1.2.2", -1}, {"1.2.3", "1.2.3", 0}, {"v1.2.3", "v1.2.2", 1}, {"v1.2.3", "v1.2.4", -1}, {"v1.2.3", "1.2.3", 0}, {"vde2faf.d2ad5.dd3", "e2faf.d2ad5.dd2", 1}, {"vde2faf.d2ad4.dd3", "vde2faf.d2ad5.dd3", -1}, {"vfe2faf.d2ad5.dd3", "ve2faf.d2ad5.dd3", 0}, {"1.2.3", "vdafe2faf.d2ad5.dd3", -1}, {"v1.2.3", "vdafe2faf.d2ad5.dd3", -1}}
for _, tc := range testCases {
got := super.CompareVersion(tc.version1, tc.version2)
if got != tc.want {
t.Errorf("CompareVersion(%q, %q) = %v; want %v", tc.version1, tc.version2, got, tc.want)
}
}
}
```
</details>
<details>
<summary>查看 / 收起基准测试</summary>
```go
func BenchmarkCompareVersion(b *testing.B) {
for i := 0; i < b.N; i++ {
super.CompareVersion("vfe2faf.d2ad5.dd3", "afe2faf.d2ad5.dd2")
}
}
```
</details>
***
### BitSet
### BitSet `STRUCT`
是一个可以动态增长的比特位集合
- 默认情况下将使用 64 位无符号整数来表示比特位,当需要表示的比特位超过 64 位时,将自动增长
```go
@@ -414,13 +749,76 @@ type BitSet[Bit generic.Integer] struct {
```
#### func (*BitSet) Set(bit Bit) *BitSet[Bit]
> 将指定的位 bit 设置为 1
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestBitSet_Set(t *testing.T) {
bs := super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
bs.Set(11)
bs.Set(12)
bs.Set(13)
t.Log(bs)
}
```
</details>
***
#### func (*BitSet) Del(bit Bit) *BitSet[Bit]
> 将指定的位 bit 设置为 0
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestBitSet_Del(t *testing.T) {
bs := super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
bs.Del(11)
bs.Del(12)
bs.Del(13)
bs.Del(10)
t.Log(bs)
}
```
</details>
***
#### func (*BitSet) Shrink() *BitSet[Bit]
> 将 BitSet 中的比特位集合缩小到最小
> - 正常情况下当 BitSet 中的比特位超出 64 位时,将自动增长,当 BitSet 中的比特位数量减少时,可以使用该方法将 BitSet 中的比特位集合缩小到最小
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestBitSet_Shrink(t *testing.T) {
bs := super.NewBitSet(63)
t.Log(bs.Cap())
bs.Set(200)
t.Log(bs.Cap())
bs.Del(200)
bs.Shrink()
t.Log(bs.Cap())
}
```
</details>
***
#### func (*BitSet) Cap() int
> 返回当前 BitSet 中可以表示的最大比特位数量
@@ -509,7 +907,7 @@ type BitSet[Bit generic.Integer] struct {
#### func (*BitSet) UnmarshalJSON(data []byte) error
> 实现 json.Unmarshaler 接口
***
### LossCounter
### LossCounter `STRUCT`
```go
type LossCounter struct {
@@ -526,7 +924,7 @@ type LossCounter struct {
***
#### func (*LossCounter) String() string
***
### Matcher
### Matcher `STRUCT`
匹配器
```go
type Matcher[Value any, Result any] struct {
@@ -535,7 +933,7 @@ type Matcher[Value any, Result any] struct {
d bool
}
```
### Permission
### Permission `STRUCT`
```go
type Permission[Code generic.Integer, EntityID comparable] struct {
@@ -543,7 +941,7 @@ type Permission[Code generic.Integer, EntityID comparable] struct {
l sync.RWMutex
}
```
### StackGo
### StackGo `STRUCT`
用于获取上一个协程调用的堆栈信息
- 应当最先运行 Wait 函数,然后在其他协程中调用 Stack 函数或者 GiveUp 函数
- 适用于跨协程同步通讯,例如单线程的消息处理统计耗时打印堆栈信息
@@ -567,7 +965,7 @@ type StackGo struct {
> - 在调用 Wait 函数后调用该函数,将会放弃收集消息堆栈并且释放资源
> - 在调用 GiveUp 函数后调用 Stack 函数,将会 panic
***
### VerifyHandle
### VerifyHandle `STRUCT`
校验句柄
```go
type VerifyHandle[V any] struct {

View File

@@ -1,19 +1,20 @@
# Timer
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/timer)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[RegSystemNewDayEvent](#RegSystemNewDayEvent)|注册系统新的一天事件
|[OnSystemNewDayEvent](#OnSystemNewDayEvent)|系统新的一天事件
@@ -26,71 +27,82 @@
|[GetTicker](#GetTicker)|获取标准池中的一个定时器
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[SystemNewDayEventHandle](#systemnewdayeventhandle)|暂无描述...
|[Option](#option)|暂无描述...
|[Pool](#pool)|定时器池
|[Scheduler](#scheduler)|调度器
|[Ticker](#ticker)|定时器
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[SystemNewDayEventHandle](#systemnewdayeventhandle)|暂无描述...
|`STRUCT`|[Option](#option)|暂无描述...
|`STRUCT`|[Pool](#pool)|定时器池
|`STRUCT`|[Scheduler](#scheduler)|调度器
|`STRUCT`|[Ticker](#ticker)|定时器
</details>
***
## 详情信息
#### func RegSystemNewDayEvent(ticker *Ticker, name string, trigger bool, handle SystemNewDayEventHandle)
<span id="RegSystemNewDayEvent"></span>
> 注册系统新的一天事件
> - 建议全局注册一个事件后再另行拓展
> - 将特定 name 的定时任务注册到 ticker 中,在系统时间到达每天的 00:00:00 时触发,如果 trigger 为 true则立即触发一次
***
#### func OnSystemNewDayEvent(name string)
<span id="OnSystemNewDayEvent"></span>
> 系统新的一天事件
***
#### func RegOffsetTimeNewDayEvent(ticker *Ticker, name string, offset *offset.Time, trigger bool, handle OffsetTimeNewDayEventHandle)
<span id="RegOffsetTimeNewDayEvent"></span>
> 注册偏移时间新的一天事件
> - 建议全局注册一个事件后再另行拓展
> - 与 RegSystemNewDayEvent 类似,但是触发时间为 offset 时间到达每天的 00:00:00
***
#### func OnOffsetTimeNewDayEvent(name string)
<span id="OnOffsetTimeNewDayEvent"></span>
> 偏移时间新的一天事件
***
#### func WithCaller(handle func (name string, caller func ())) Option
<span id="WithCaller"></span>
> 通过其他的 handle 执行 Caller
***
#### func WithMark(mark string) Option
<span id="WithMark"></span>
> 通过特定的标记创建定时器
***
#### func NewPool(tickerPoolSize int) *Pool
<span id="NewPool"></span>
> 创建一个定时器池,当 tickerPoolSize 小于等于 0 时,将会引发 panic可指定为 DefaultTickerPoolSize
***
#### func SetPoolSize(size int)
<span id="SetPoolSize"></span>
> 设置标准池定时器池大小
> - 默认值为 DefaultTickerPoolSize当定时器池中的定时器不足时会自动创建新的定时器当定时器释放时会将多余的定时器进行释放否则将放入定时器池中
***
#### func GetTicker(size int, options ...Option) *Ticker
<span id="GetTicker"></span>
> 获取标准池中的一个定时器
***
### SystemNewDayEventHandle
### SystemNewDayEventHandle `STRUCT`
```go
type SystemNewDayEventHandle struct{}
type SystemNewDayEventHandle func()
```
### Option
### Option `STRUCT`
```go
type Option struct{}
type Option func(ticker *Ticker)
```
### Pool
### Pool `STRUCT`
定时器池
```go
type Pool struct {
@@ -111,7 +123,7 @@ type Pool struct {
> 释放定时器池的资源,释放后由其产生的 Ticker 在 Ticker.Release 后将不再回到池中,而是直接释放
> - 虽然定时器池已被释放,但是依旧可以产出 Ticker
***
### Scheduler
### Scheduler `STRUCT`
调度器
```go
type Scheduler struct {
@@ -138,7 +150,7 @@ type Scheduler struct {
#### func (*Scheduler) Caller()
> 可由外部发起调用的执行函数
***
### Ticker
### Ticker `STRUCT`
定时器
```go
type Ticker struct {
@@ -168,6 +180,32 @@ type Ticker struct {
***
#### func (*Ticker) Cron(name string, expression string, handleFunc interface {}, args ...interface {})
> 通过 cron 表达式设置一个调度器,当 cron 表达式错误时,将会引发 panic
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestTicker_Cron(t *testing.T) {
ticker := timer.GetTicker(10)
ticker.After("1_sec", time.Second, func() {
t.Log(time.Now().Format(time.DateTime), "1_sec")
})
ticker.Loop("1_sec_loop_3", 0, time.Second, 3, func() {
t.Log(time.Now().Format(time.DateTime), "1_sec_loop_3")
})
ticker.Cron("5_sec_cron", "0/5 * * * * * ?", func() {
t.Log(time.Now().Format(time.DateTime), "5_sec_cron")
})
time.Sleep(times.Week)
}
```
</details>
***
#### func (*Ticker) CronByInstantly(name string, expression string, handleFunc interface {}, args ...interface {})
> 与 Cron 相同,但是会立即执行一次

View File

@@ -1,19 +1,20 @@
# Times
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/times)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[CalcNextSec](#CalcNextSec)|计算下一个N秒在多少秒之后
|[CalcNextSecWithTime](#CalcNextSecWithTime)|计算下一个N秒在多少秒之后
@@ -65,23 +66,37 @@
|[NewPeriodWithNanosecond](#NewPeriodWithNanosecond)|创建一个时间段,从 t 开始,持续 nanosecond 纳秒
> 结构体定义
> 类型定义
|结构体|描述
|:--|:--
|[StateLine](#stateline)|状态时间线
|[Period](#period)|表示一个时间段
|类型|名称|描述
|:--|:--|:--
|`STRUCT`|[StateLine](#stateline)|状态时间线
|`STRUCT`|[Period](#period)|表示一个时间段
</details>
***
## 详情信息
#### func CalcNextSec(sec int) int
<span id="CalcNextSec"></span>
> 计算下一个N秒在多少秒之后
***
#### func CalcNextSecWithTime(t time.Time, sec int) int
<span id="CalcNextSecWithTime"></span>
> 计算下一个N秒在多少秒之后
示例代码:
```go
func ExampleCalcNextSecWithTime() {
now := time.Date(2023, 9, 20, 0, 0, 3, 0, time.Local)
fmt.Println(times.CalcNextSecWithTime(now, 10))
}
```
***
#### func CalcNextTimeWithRefer(now time.Time, refer time.Duration) time.Time
<span id="CalcNextTimeWithRefer"></span>
@@ -90,192 +105,301 @@
> - 假设当 now 为 14:15:16 参考时间为 20 分钟, 则返回 14:20:00
>
> 当 refer 小于 1 分钟时,将会返回当前时间
***
#### func IntervalFormatSet(intervalType int, str string)
<span id="IntervalFormatSet"></span>
> 针对 IntervalFormat 函数设置格式化内容
***
#### func IntervalFormat(time1 time.Time, time2 time.Time) string
<span id="IntervalFormat"></span>
> 返回指定时间戳之间的间隔
> - 使用传入的时间进行计算换算,将结果体现为几年前、几天前、几小时前、几分钟前、几秒前。
***
#### func GetMonthDays(t time.Time) int
<span id="GetMonthDays"></span>
> 获取一个时间当月共有多少天
***
#### func WeekDay(t time.Time) int
<span id="WeekDay"></span>
> 获取一个时间是星期几
> - 1 ~ 7
***
#### func GetNextDayInterval(t time.Time) time.Duration
<span id="GetNextDayInterval"></span>
> 获取一个时间到下一天间隔多少秒
***
#### func GetToday(t time.Time) time.Time
<span id="GetToday"></span>
> 获取一个时间的今天
***
#### func GetSecond(d time.Duration) int
<span id="GetSecond"></span>
> 获取共有多少秒
***
#### func IsSameDay(t1 time.Time, t2 time.Time) bool
<span id="IsSameDay"></span>
> 两个时间是否是同一天
***
#### func IsSameHour(t1 time.Time, t2 time.Time) bool
<span id="IsSameHour"></span>
> 两个时间是否是同一小时
***
#### func GetMondayZero(t time.Time) time.Time
<span id="GetMondayZero"></span>
> 获取本周一零点
***
#### func Date(year int, month time.Month, day int) time.Time
<span id="Date"></span>
> 返回一个特定日期的时间
***
#### func DateWithHMS(year int, month time.Month, day int, hour int, min int, sec int) time.Time
<span id="DateWithHMS"></span>
> 返回一个精确到秒的时间
***
#### func GetDeltaDay(t1 time.Time, t2 time.Time) int
<span id="GetDeltaDay"></span>
> 获取两个时间需要加减的天数
***
#### func GetDeltaWeek(t1 time.Time, t2 time.Time) int
<span id="GetDeltaWeek"></span>
> 获取两个时间需要加减的周数
***
#### func GetHSMFromString(timeStr string, layout string) (hour int, min int, sec int)
<span id="GetHSMFromString"></span>
> 从时间字符串中获取时分秒
***
#### func GetTimeFromString(timeStr string, layout string) time.Time
<span id="GetTimeFromString"></span>
> 将时间字符串转化为时间
***
#### func GetDayZero(t time.Time, day int) time.Time
<span id="GetDayZero"></span>
> 获取 t 增加 day 天后的零点时间
***
#### func GetYesterday(t time.Time) time.Time
<span id="GetYesterday"></span>
> 获取昨天
***
#### func GetDayLast(t time.Time) time.Time
<span id="GetDayLast"></span>
> 获取某天的最后一刻
> - 最后一刻即 23:59:59
***
#### func GetYesterdayLast(t time.Time) time.Time
<span id="GetYesterdayLast"></span>
> 获取昨天最后一刻
***
#### func GetMinuteStart(t time.Time) time.Time
<span id="GetMinuteStart"></span>
> 获取一个时间的 0 秒
***
#### func GetMinuteEnd(t time.Time) time.Time
<span id="GetMinuteEnd"></span>
> 获取一个时间的 59 秒
***
#### func GetHourStart(t time.Time) time.Time
<span id="GetHourStart"></span>
> 获取一个时间的 0 分 0 秒
***
#### func GetHourEnd(t time.Time) time.Time
<span id="GetHourEnd"></span>
> 获取一个时间的 59 分 59 秒
***
#### func GetMonthStart(t time.Time) time.Time
<span id="GetMonthStart"></span>
> 获取一个时间的月初
***
#### func GetMonthEnd(t time.Time) time.Time
<span id="GetMonthEnd"></span>
> 获取一个时间的月末
***
#### func GetYearStart(t time.Time) time.Time
<span id="GetYearStart"></span>
> 获取一个时间的年初
***
#### func GetYearEnd(t time.Time) time.Time
<span id="GetYearEnd"></span>
> 获取一个时间的年末
***
#### func NewStateLine(zero State) *StateLine[State]
<span id="NewStateLine"></span>
> 创建一个从左向右由早到晚的状态时间线
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewStateLine(t *testing.T) {
sl := times.NewStateLine(0)
sl.AddState(1, time.Now())
sl.AddState(2, time.Now().Add(-times.Hour))
sl.Range(func(index int, state int, ts time.Time) bool {
t.Log(index, state, ts)
return true
})
t.Log(sl.GetStateByTime(time.Now()))
}
```
</details>
***
#### func SetGlobalTimeOffset(offset time.Duration)
<span id="SetGlobalTimeOffset"></span>
> 设置全局时间偏移量
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestSetGlobalTimeOffset(t *testing.T) {
fmt.Println(time.Now())
times.SetGlobalTimeOffset(-times.Hour)
fmt.Println(time.Now())
times.SetGlobalTimeOffset(times.Hour)
fmt.Println(time.Now())
fmt.Println(times.NowByNotOffset())
}
```
</details>
***
#### func NowByNotOffset() time.Time
<span id="NowByNotOffset"></span>
> 获取未偏移的当前时间
***
#### func GetGlobalTimeOffset() time.Duration
<span id="GetGlobalTimeOffset"></span>
> 获取全局时间偏移量
***
#### func ResetGlobalTimeOffset()
<span id="ResetGlobalTimeOffset"></span>
> 重置全局时间偏移量
***
#### func NewPeriod(start time.Time, end time.Time) Period
<span id="NewPeriod"></span>
> 创建一个时间段
> - 如果 start 比 end 晚,则会自动交换两个时间
***
#### func NewPeriodWindow(t time.Time, size time.Duration) Period
<span id="NewPeriodWindow"></span>
> 创建一个特定长度的时间窗口
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewPeriodWindow(t *testing.T) {
cur := time.Now()
fmt.Println(cur)
window := times.NewPeriodWindow(cur, times.Day)
fmt.Println(window)
}
```
</details>
***
#### func NewPeriodWindowWeek(t time.Time) Period
<span id="NewPeriodWindowWeek"></span>
> 创建一周长度的时间窗口,从周一零点开始至周日 23:59:59 结束
***
#### func NewPeriodWithTimeArray(times [2]time.Time) Period
<span id="NewPeriodWithTimeArray"></span>
> 创建一个时间段
***
#### func NewPeriodWithDayZero(t time.Time, day int) Period
<span id="NewPeriodWithDayZero"></span>
> 创建一个时间段,从 t 开始,持续到 day 天后的 0 点
***
#### func NewPeriodWithDay(t time.Time, day int) Period
<span id="NewPeriodWithDay"></span>
> 创建一个时间段,从 t 开始,持续 day 天
***
#### func NewPeriodWithHour(t time.Time, hour int) Period
<span id="NewPeriodWithHour"></span>
> 创建一个时间段,从 t 开始,持续 hour 小时
***
#### func NewPeriodWithMinute(t time.Time, minute int) Period
<span id="NewPeriodWithMinute"></span>
> 创建一个时间段,从 t 开始,持续 minute 分钟
***
#### func NewPeriodWithSecond(t time.Time, second int) Period
<span id="NewPeriodWithSecond"></span>
> 创建一个时间段,从 t 开始,持续 second 秒
***
#### func NewPeriodWithMillisecond(t time.Time, millisecond int) Period
<span id="NewPeriodWithMillisecond"></span>
> 创建一个时间段,从 t 开始,持续 millisecond 毫秒
***
#### func NewPeriodWithMicrosecond(t time.Time, microsecond int) Period
<span id="NewPeriodWithMicrosecond"></span>
> 创建一个时间段,从 t 开始,持续 microsecond 微秒
***
#### func NewPeriodWithNanosecond(t time.Time, nanosecond int) Period
<span id="NewPeriodWithNanosecond"></span>
> 创建一个时间段,从 t 开始,持续 nanosecond 纳秒
***
### StateLine
### StateLine `STRUCT`
状态时间线
```go
type StateLine[State generic.Basic] struct {
@@ -362,10 +486,10 @@ type StateLine[State generic.Basic] struct {
#### func (*StateLine) RangeReverse(handler func (index int, state State, t time.Time) bool)
> 按照时间逆序遍历时间线
***
### Period
### Period `STRUCT`
表示一个时间段
```go
type Period struct{}
type Period [2]time.Time
```
#### func (Period) Start() time.Time
> 返回时间段的开始时间

View File

@@ -1,32 +1,28 @@
# Xlsxtool
[![Go doc](https://img.shields.io/badge/go.dev-reference-brightgreen?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/kercylan98/minotaur/xlsxtool)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat)
## 目录
列出了该 `package` 下所有的函数,可通过目录进行快捷跳转 ❤️
## 目录导航
列出了该 `package` 下所有的函数及类型定义,可通过目录导航进行快捷跳转 ❤️
<details>
<summary>展开 / 折叠目录</summary
<summary>展开 / 折叠目录导航</summary>
> 包级函数定义
|函数|描述
|函数名称|描述
|:--|:--
|[GetSheetMatrix](#GetSheetMatrix)|将sheet转换为二维矩阵
> 结构体定义
|结构体|描述
|:--|:--
</details>
***
## 详情信息
#### func GetSheetMatrix(sheet *xlsx.Sheet) *matrix.Matrix[*xlsx.Cell]
<span id="GetSheetMatrix"></span>
> 将sheet转换为二维矩阵
***