docs: 完善根目录 README.md,增加项目实践记录内容。生成子目录 README.md 文档

This commit is contained in:
kercylan98 2024-01-24 11:12:34 +08:00
parent ebe7a70496
commit fc14e73801
11 changed files with 2027 additions and 35 deletions

BIN
.github/images/pod.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
.github/images/yc-cpu.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
.github/images/yc-event.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
.github/images/yc-memory.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
.github/images/yc1.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
.github/images/yc2.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -1,11 +1,53 @@
# Minotaur # Minotaur
Minotaur 是一个用于服务端开发的支持库,其中采用了大量泛型设计,主要被用于游戏服务器开发,但由于拥有大量通用的功能,也常被用于 WEB 开发。
***
[![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) [![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)
![](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat) ![license](https://img.shields.io/github/license/kercylan98/minotaur)
![](https://komarev.com/ghpvc/?username=kercylan98)
<a target="_blank" href="https://goreportcard.com/report/github.com/kercylan98/minotaur"><img src="https://goreportcard.com/badge/github.com/kercylan98/minotaur?style=flat-square" /></a> <a target="_blank" href="https://goreportcard.com/report/github.com/kercylan98/minotaur"><img src="https://goreportcard.com/badge/github.com/kercylan98/minotaur?style=flat-square" /></a>
Minotaur 是一个基于 Golang 1.20 编写的服务端开发支持库,其中采用了大量泛型设计,主要被用于游戏服务器开发,但由于拥有大量通用的功能,也常被用于 WEB 开发。 ![go version](https://img.shields.io/github/go-mod/go-version/kercylan98/minotaur?logo=go&style=flat)
![tag](https://img.shields.io/github/v/tag/kercylan98/minotaur?logo=github&style=flat)
![views](https://komarev.com/ghpvc/?username=kercylan98&color=blue&style=flat)
![email](https://img.shields.io/badge/Email-kercylan@gmail.com-green.svg?style=flat&logo=gmail&link=mailto:kercylan@gmail.com)
![qq-group](https://img.shields.io/badge/QQ%20Group-758219443-green.svg?style=flat&logo=tencent-qq&link=https://qm.qq.com/cgi-bin/qm/qr?k=WzRWJIDLzuJbH6-VjdFiTCd1_qA_Ug-D&jump_from=webapi&authKey=ktLEw3XyY9yO+i9rPbI6Fk0UA0uEhACcUidOFdblaiToZtbHcXyU7sFb31FEc9JJ&noverify=0)
![telegram](https://img.shields.io/badge/Telegram-ziv__siren-green.svg?style=flat&logo=telegram&link=https://telegram.me/ziv_siren)
> - 这是支持快速搭建多功能游戏服务器及 HTTP 服务器的 `Golang` 服务端框架;
> - 网络传输基于 [`gorilla/websocket`](https://github.com/gorilla/websocket)、[`gin-gonic/gin`](https://github.com/gin-gonic/gin)、[`grpc/grpc-go`](https://github.com/grpc/grpc-go)、[`panjf2000/gnet`](https://github.com/panjf2000/gnet)、[`xtaci/kcp-go`](https://github.com/xtaci/kcp-go) 构建;
> - 该项目的目标是提供一个简单、高效、可扩展的游戏服务器框架,让开发者可以专注于游戏逻辑的开发,而不用花费大量时间在网络传输、配置导表、日志、监控等基础功能的开发上;
***
在 Minotaur 中不包括任何跨服实现,但支持基于多级路由器快速实现跨服功能。推荐使用 [`NATS.io`](https://nats.io/) 作为跨服消息中间件。
- 目前已实践的弹幕游戏项目以 `NATS.io` 作为消息队列,实现了跨服、埋点日志收集等功能,部署在 `Kubernetes` 集群中;
- 该项目客户端与服务端采用 `WebSocket` 进行通讯,服务端暴露 `HTTP` 接口接收互动数据消息回调,通过负载均衡器进入 `Kubernetes` 集群中的 `Minotaur` 服务,最终通过 `NATS.io` 消息队列转发至对应所在的 `Pod` 中进行处理;
<details>
<summary>关于 Pod 配置参数及非极限压测数据</summary>
> 本次压测 `Pod` 扩容数量为 1但由于压测连接是最开始就建立好的所以该扩容的 `Pod` 并没有接受到压力。
> 理论上来说该 `Pod` 也应该接受 `HTTP` 回调压力,实测过程中,这个扩容的 `Pod` 没有接受到任何压力
**Pod 配置参数**
![pod](.github/images/pod.png)
**压测结果**
![压测数据](.github/images/yc1.png)
![压测数据](.github/images/yc2.png)
**监控数据**
![事件](./.github/images/yc-event.png)
![CPU](./.github/images/yc-cpu.png)
![内存](./.github/images/yc-memory.png)
</details>
***
## 特色内容 ## 特色内容
```mermaid ```mermaid

View File

@ -47,6 +47,8 @@ server 提供了包含多种网络类型的服务器实现
|[WithWebsocketMessageType](#WithWebsocketMessageType)|设置仅支持特定类型的Websocket消息 |[WithWebsocketMessageType](#WithWebsocketMessageType)|设置仅支持特定类型的Websocket消息
|[WithPProf](#WithPProf)|通过性能分析工具PProf创建服务器 |[WithPProf](#WithPProf)|通过性能分析工具PProf创建服务器
|[New](#New)|根据特定网络类型创建一个服务器 |[New](#New)|根据特定网络类型创建一个服务器
|[LoadData](#LoadData)|加载绑定的服务器数据
|[BindData](#BindData)|绑定数据到特定服务器
|[BindService](#BindService)|绑定服务到特定 Server被绑定的服务将会在 Server 初始化时执行 Service.OnInit 方法 |[BindService](#BindService)|绑定服务到特定 Server被绑定的服务将会在 Server 初始化时执行 Service.OnInit 方法
@ -515,6 +517,16 @@ func TestNew(t *testing.T) {
</details> </details>
***
#### func LoadData\[T any\](srv *Server, name string, data any) T
<span id="LoadData"></span>
> 加载绑定的服务器数据
***
#### func BindData(srv *Server, name string, data any)
<span id="BindData"></span>
> 绑定数据到特定服务器
*** ***
#### func BindService(srv *Server, services ...Service) #### func BindService(srv *Server, services ...Service)
<span id="BindService"></span> <span id="BindService"></span>
@ -1340,6 +1352,7 @@ type Server struct {
systemSignal chan os.Signal systemSignal chan os.Signal
closeChannel chan struct{} closeChannel chan struct{}
multipleRuntimeErrorChan chan error multipleRuntimeErrorChan chan error
data map[string]any
messageCounter atomic.Int64 messageCounter atomic.Int64
addr string addr string
network Network network Network
@ -1347,6 +1360,18 @@ type Server struct {
services []func() services []func()
} }
``` ```
<span id="struct_Server_LoadData"></span>
#### func (*Server) LoadData(name string, data any) any
> 加载绑定的服务器数据
***
<span id="struct_Server_BindData"></span>
#### func (*Server) BindData(name string, data any)
> 绑定数据到特定服务器
***
<span id="struct_Server_Run"></span> <span id="struct_Server_Run"></span>
#### func (*Server) Run(addr string) (err error) #### func (*Server) Run(addr string) (err error)

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,7 @@
|:--|:-- |:--|:--
|[NewFloat](#NewFloat)|创建一个 Float |[NewFloat](#NewFloat)|创建一个 Float
|[NewFloatByString](#NewFloatByString)|通过字符串创建一个 Float |[NewFloatByString](#NewFloatByString)|通过字符串创建一个 Float
|[NewInt](#NewInt)|创建一个 Int |[NewInt](#NewInt)|创建一个 Int 对象,该对象的值为 x
|[NewIntByString](#NewIntByString)|通过字符串创建一个 Int
> 类型定义 > 类型定义
@ -45,15 +44,88 @@
> - 如果字符串不是一个合法的数字,则返回 0 > - 如果字符串不是一个合法的数字,则返回 0
*** ***
#### func NewInt\[T generic.Number\](x T) *Int #### func NewInt\[T generic.Basic\](x T) *Int
<span id="NewInt"></span> <span id="NewInt"></span>
> 创建一个 Int > 创建一个 Int 对象,该对象的值为 x
**示例代码:**
该案例展示了 NewInt 对各种基本类型的支持及用法
```go
func ExampleNewInt() {
fmt.Println(huge.NewInt("12345678900000000"))
fmt.Println(huge.NewInt(1234567890))
fmt.Println(huge.NewInt(true))
fmt.Println(huge.NewInt(123.123))
fmt.Println(huge.NewInt(byte(1)))
}
```
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewInt(t *testing.T) {
var cases = []struct {
name string
nil bool
in int64
mul int64
want string
}{{name: "TestNewIntNegative", in: -1, want: "-1"}, {name: "TestNewIntZero", in: 0, want: "0"}, {name: "TestNewIntPositive", in: 1, want: "1"}, {name: "TestNewIntMax", in: 9223372036854775807, want: "9223372036854775807"}, {name: "TestNewIntMin", in: -9223372036854775808, want: "-9223372036854775808"}, {name: "TestNewIntMulNegative", in: -9223372036854775808, mul: 10000000, want: "-92233720368547758080000000"}, {name: "TestNewIntMulPositive", in: 9223372036854775807, mul: 10000000, want: "92233720368547758070000000"}, {name: "TestNewIntNil", nil: true, want: "0"}, {name: "TestNewIntNilMul", nil: true, mul: 10000000, want: "0"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var got *huge.Int
switch {
case c.nil:
if c.mul > 0 {
got = huge.NewInt(0).MulInt64(c.mul)
}
case c.mul == 0:
got = huge.NewInt(c.in)
default:
got = huge.NewInt(c.in).MulInt64(c.mul)
}
if s := got.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, got.String())
} else {
t.Log(s)
}
})
}
t.Run("TestNewIntFromString", func(t *testing.T) {
if got := huge.NewInt("1234567890123456789012345678901234567890"); got.String() != "1234567890123456789012345678901234567890" {
t.Fatalf("want: %s, got: %s", "1234567890123456789012345678901234567890", got.String())
}
})
t.Run("TestNewIntFromInt", func(t *testing.T) {
if got := huge.NewInt(1234567890); got.String() != "1234567890" {
t.Fatalf("want: %s, got: %s", "1234567890", got.String())
}
})
t.Run("TestNewIntFromBool", func(t *testing.T) {
if got := huge.NewInt(true); got.String() != "1" {
t.Fatalf("want: %s, got: %s", "1", got.String())
}
})
t.Run("TestNewIntFromFloat", func(t *testing.T) {
if got := huge.NewInt(1234567890.1234567890); got.String() != "1234567890" {
t.Fatalf("want: %s, got: %s", "1234567890", got.String())
}
})
}
```
</details>
***
#### func NewIntByString(i string) *Int
<span id="NewIntByString"></span>
> 通过字符串创建一个 Int
> - 如果字符串不是一个合法的数字,则返回 0
*** ***
<span id="struct_Float"></span> <span id="struct_Float"></span>
@ -190,71 +262,689 @@ type Int big.Int
<span id="struct_Int_Copy"></span> <span id="struct_Int_Copy"></span>
#### func (*Int) Copy() *Int #### func (*Int) Copy() *Int
> 拷贝当前 Int 对象
**示例代码:**
```go
func ExampleInt_Copy() {
var a = huge.NewInt(1234567890)
var b = a.Copy().SetInt64(9876543210)
fmt.Println(a)
fmt.Println(b)
}
```
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_Copy(t *testing.T) {
var cases = []struct {
name string
in int64
want string
}{{name: "TestIntCopyNegative", in: -1, want: "-1"}, {name: "TestIntCopyZero", in: 0, want: "0"}, {name: "TestIntCopyPositive", in: 1, want: "1"}, {name: "TestIntCopyMax", in: 9223372036854775807, want: "9223372036854775807"}, {name: "TestIntCopyMin", in: -9223372036854775808, want: "-9223372036854775808"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in = huge.NewInt(c.in)
var got = in.Copy()
if in.Int64() != c.in {
t.Fatalf("want: %d, got: %d", c.in, in.Int64())
}
if s := got.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, got.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_Set"></span> <span id="struct_Int_Set"></span>
#### func (*Int) Set(i *Int) *Int #### func (*Int) Set(i *Int) *Int
> 设置当前 Int 对象的值为 i
**示例代码:**
```go
func ExampleInt_Set() {
var a = huge.NewInt(1234567890)
var b = huge.NewInt(9876543210)
fmt.Println(a)
a.Set(b)
fmt.Println(a)
}
```
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_Set(t *testing.T) {
var cases = []struct {
name string
in int64
want string
}{{name: "TestIntSetNegative", in: -1, want: "-1"}, {name: "TestIntSetZero", in: 0, want: "0"}, {name: "TestIntSetPositive", in: 1, want: "1"}, {name: "TestIntSetMax", in: 9223372036854775807, want: "9223372036854775807"}, {name: "TestIntSetMin", in: -9223372036854775808, want: "-9223372036854775808"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.Set(huge.NewInt(c.in))
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
***
<span id="struct_Int_SetString"></span>
#### func (*Int) SetString(i string) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetString(t *testing.T) {
var cases = []struct {
name string
in string
want string
}{{name: "TestIntSetStringNegative", in: "-1", want: "-1"}, {name: "TestIntSetStringZero", in: "0", want: "0"}, {name: "TestIntSetStringPositive", in: "1", want: "1"}, {name: "TestIntSetStringMax", in: "9223372036854775807", want: "9223372036854775807"}, {name: "TestIntSetStringMin", in: "-9223372036854775808", want: "-9223372036854775808"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetString(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_SetInt"></span> <span id="struct_Int_SetInt"></span>
#### func (*Int) SetInt(i int) *Int #### func (*Int) SetInt(i int) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetInt(t *testing.T) {
var cases = []struct {
name string
in int64
want string
}{{name: "TestIntSetIntNegative", in: -1, want: "-1"}, {name: "TestIntSetIntZero", in: 0, want: "0"}, {name: "TestIntSetIntPositive", in: 1, want: "1"}, {name: "TestIntSetIntMax", in: 9223372036854775807, want: "9223372036854775807"}, {name: "TestIntSetIntMin", in: -9223372036854775808, want: "-9223372036854775808"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetInt64(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_SetInt8"></span> <span id="struct_Int_SetInt8"></span>
#### func (*Int) SetInt8(i int8) *Int #### func (*Int) SetInt8(i int8) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetInt8(t *testing.T) {
var cases = []struct {
name string
in int8
want string
}{{name: "TestIntSetInt8Negative", in: -1, want: "-1"}, {name: "TestIntSetInt8Zero", in: 0, want: "0"}, {name: "TestIntSetInt8Positive", in: 1, want: "1"}, {name: "TestIntSetInt8Max", in: 127, want: "127"}, {name: "TestIntSetInt8Min", in: -128, want: "-128"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetInt8(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_SetInt16"></span> <span id="struct_Int_SetInt16"></span>
#### func (*Int) SetInt16(i int16) *Int #### func (*Int) SetInt16(i int16) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetInt16(t *testing.T) {
var cases = []struct {
name string
in int16
want string
}{{name: "TestIntSetInt16Negative", in: -1, want: "-1"}, {name: "TestIntSetInt16Zero", in: 0, want: "0"}, {name: "TestIntSetInt16Positive", in: 1, want: "1"}, {name: "TestIntSetInt16Max", in: 32767, want: "32767"}, {name: "TestIntSetInt16Min", in: -32768, want: "-32768"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetInt16(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_SetInt32"></span> <span id="struct_Int_SetInt32"></span>
#### func (*Int) SetInt32(i int32) *Int #### func (*Int) SetInt32(i int32) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetInt32(t *testing.T) {
var cases = []struct {
name string
in int32
want string
}{{name: "TestIntSetInt32Negative", in: -1, want: "-1"}, {name: "TestIntSetInt32Zero", in: 0, want: "0"}, {name: "TestIntSetInt32Positive", in: 1, want: "1"}, {name: "TestIntSetInt32Max", in: 2147483647, want: "2147483647"}, {name: "TestIntSetInt32Min", in: -2147483648, want: "-2147483648"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetInt32(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_SetInt64"></span> <span id="struct_Int_SetInt64"></span>
#### func (*Int) SetInt64(i int64) *Int #### func (*Int) SetInt64(i int64) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetInt64(t *testing.T) {
var cases = []struct {
name string
in int64
want string
}{{name: "TestIntSetInt64Negative", in: -1, want: "-1"}, {name: "TestIntSetInt64Zero", in: 0, want: "0"}, {name: "TestIntSetInt64Positive", in: 1, want: "1"}, {name: "TestIntSetInt64Max", in: 9223372036854775807, want: "9223372036854775807"}, {name: "TestIntSetInt64Min", in: -9223372036854775808, want: "-9223372036854775808"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetInt64(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_SetUint"></span> <span id="struct_Int_SetUint"></span>
#### func (*Int) SetUint(i uint) *Int #### func (*Int) SetUint(i uint) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetUint(t *testing.T) {
var cases = []struct {
name string
in uint64
want string
}{{name: "TestIntSetUintNegative", in: 0, want: "0"}, {name: "TestIntSetUintZero", in: 0, want: "0"}, {name: "TestIntSetUintPositive", in: 1, want: "1"}, {name: "TestIntSetUintMax", in: 18446744073709551615, want: "18446744073709551615"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetUint64(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_SetUint8"></span> <span id="struct_Int_SetUint8"></span>
#### func (*Int) SetUint8(i uint8) *Int #### func (*Int) SetUint8(i uint8) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetUint8(t *testing.T) {
var cases = []struct {
name string
in uint8
want string
}{{name: "TestIntSetUint8Negative", in: 0, want: "0"}, {name: "TestIntSetUint8Zero", in: 0, want: "0"}, {name: "TestIntSetUint8Positive", in: 1, want: "1"}, {name: "TestIntSetUint8Max", in: 255, want: "255"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetUint8(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_SetUint16"></span> <span id="struct_Int_SetUint16"></span>
#### func (*Int) SetUint16(i uint16) *Int #### func (*Int) SetUint16(i uint16) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetUint16(t *testing.T) {
var cases = []struct {
name string
in uint16
want string
}{{name: "TestIntSetUint16Negative", in: 0, want: "0"}, {name: "TestIntSetUint16Zero", in: 0, want: "0"}, {name: "TestIntSetUint16Positive", in: 1, want: "1"}, {name: "TestIntSetUint16Max", in: 65535, want: "65535"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetUint16(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_SetUint32"></span> <span id="struct_Int_SetUint32"></span>
#### func (*Int) SetUint32(i uint32) *Int #### func (*Int) SetUint32(i uint32) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetUint32(t *testing.T) {
var cases = []struct {
name string
in uint32
want string
}{{name: "TestIntSetUint32Negative", in: 0, want: "0"}, {name: "TestIntSetUint32Zero", in: 0, want: "0"}, {name: "TestIntSetUint32Positive", in: 1, want: "1"}, {name: "TestIntSetUint32Max", in: 4294967295, want: "4294967295"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetUint32(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_SetUint64"></span> <span id="struct_Int_SetUint64"></span>
#### func (*Int) SetUint64(i uint64) *Int #### func (*Int) SetUint64(i uint64) *Int
> 设置当前 Int 对象的值为 i
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetUint64(t *testing.T) {
var cases = []struct {
name string
in uint64
want string
}{{name: "TestIntSetUint64Negative", in: 0, want: "0"}, {name: "TestIntSetUint64Zero", in: 0, want: "0"}, {name: "TestIntSetUint64Positive", in: 1, want: "1"}, {name: "TestIntSetUint64Max", in: 18446744073709551615, want: "18446744073709551615"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetUint64(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
***
<span id="struct_Int_SetFloat32"></span>
#### func (*Int) SetFloat32(i float32) *Int
> 设置当前 Int 对象的值为 i 向下取整后的值
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetFloat32(t *testing.T) {
var cases = []struct {
name string
in float32
want string
}{{name: "TestIntSetFloat32Negative", in: -1.1, want: "-1"}, {name: "TestIntSetFloat32Zero", in: 0, want: "0"}, {name: "TestIntSetFloat32Positive", in: 1.1, want: "1"}, {name: "TestIntSetFloat32Max", in: 9223372036854775807, want: "9223372036854775807"}, {name: "TestIntSetFloat32Min", in: -9223372036854775808, want: "-9223372036854775808"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetFloat32(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
***
<span id="struct_Int_SetFloat64"></span>
#### func (*Int) SetFloat64(i float64) *Int
> 设置当前 Int 对象的值为 i 向下取整后的值
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetFloat64(t *testing.T) {
var cases = []struct {
name string
in float64
want string
}{{name: "TestIntSetFloat64Negative", in: -1.1, want: "-1"}, {name: "TestIntSetFloat64Zero", in: 0, want: "0"}, {name: "TestIntSetFloat64Positive", in: 1.1, want: "1"}, {name: "TestIntSetFloat64Max", in: 9223372036854775807, want: "9223372036854775807"}, {name: "TestIntSetFloat64Min", in: -9223372036854775808, want: "-9223372036854775808"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetFloat64(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
***
<span id="struct_Int_SetBool"></span>
#### func (*Int) SetBool(i bool) *Int
> 设置当前 Int 对象的值为 i当 i 为 true 时,值为 1当 i 为 false 时,值为 0
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_SetBool(t *testing.T) {
var cases = []struct {
name string
in bool
want string
}{{name: "TestIntSetBoolFalse", in: false, want: "0"}, {name: "TestIntSetBoolTrue", in: true, want: "1"}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var in *huge.Int
in = in.SetBool(c.in)
if s := in.String(); s != c.want {
t.Fatalf("want: %s, got: %s", c.want, in.String())
} else {
t.Log(s)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_IsZero"></span> <span id="struct_Int_IsZero"></span>
#### func (*Int) IsZero() bool #### func (*Int) IsZero() bool
> 判断当前 Int 对象的值是否为 0
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_IsZero(t *testing.T) {
var cases = []struct {
name string
in int64
want bool
}{{name: "TestIntIsZeroNegative", in: -1, want: false}, {name: "TestIntIsZeroZero", in: 0, want: true}, {name: "TestIntIsZeroPositive", in: 1, want: false}, {name: "TestIntIsZeroMax", in: 9223372036854775807, want: false}, {name: "TestIntIsZeroMin", in: -9223372036854775808, want: false}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := huge.NewInt(c.in).IsZero(); got != c.want {
t.Fatalf("want: %t, got: %t", c.want, got)
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_ToBigint"></span> <span id="struct_Int_ToBigint"></span>
#### func (*Int) ToBigint() *big.Int #### func (*Int) ToBigint() *big.Int
> 转换为 *big.Int
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestInt_ToBigint(t *testing.T) {
var cases = []struct {
name string
in int64
want *big.Int
}{{name: "TestIntToBigintNegative", in: -1, want: big.NewInt(-1)}, {name: "TestIntToBigintZero", in: 0, want: big.NewInt(0)}, {name: "TestIntToBigintPositive", in: 1, want: big.NewInt(1)}, {name: "TestIntToBigintMax", in: 9223372036854775807, want: big.NewInt(9223372036854775807)}, {name: "TestIntToBigintMin", in: -9223372036854775808, want: big.NewInt(-9223372036854775808)}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := huge.NewInt(c.in).ToBigint(); got.Cmp(c.want) != 0 {
t.Fatalf("want: %s, got: %s", c.want.String(), got.String())
}
})
}
}
```
</details>
*** ***
<span id="struct_Int_Cmp"></span> <span id="struct_Int_Cmp"></span>
@ -266,46 +956,49 @@ type Int big.Int
<span id="struct_Int_GreaterThan"></span> <span id="struct_Int_GreaterThan"></span>
#### func (*Int) GreaterThan(i *Int) bool #### func (*Int) GreaterThan(i *Int) bool
> 大于 > 检查 slf 是否大于 i
*** ***
<span id="struct_Int_GreaterThanOrEqualTo"></span> <span id="struct_Int_GreaterThanOrEqualTo"></span>
#### func (*Int) GreaterThanOrEqualTo(i *Int) bool #### func (*Int) GreaterThanOrEqualTo(i *Int) bool
> 大于或等于 > 检查 slf 是否大于或等于 i
*** ***
<span id="struct_Int_LessThan"></span> <span id="struct_Int_LessThan"></span>
#### func (*Int) LessThan(i *Int) bool #### func (*Int) LessThan(i *Int) bool
> 小于 > 检查 slf 是否小于 i
*** ***
<span id="struct_Int_LessThanOrEqualTo"></span> <span id="struct_Int_LessThanOrEqualTo"></span>
#### func (*Int) LessThanOrEqualTo(i *Int) bool #### func (*Int) LessThanOrEqualTo(i *Int) bool
> 小于或等于 > 检查 slf 是否小于或等于 i
*** ***
<span id="struct_Int_EqualTo"></span> <span id="struct_Int_EqualTo"></span>
#### func (*Int) EqualTo(i *Int) bool #### func (*Int) EqualTo(i *Int) bool
> 等于 > 检查 slf 是否等于 i
*** ***
<span id="struct_Int_Int64"></span> <span id="struct_Int_Int64"></span>
#### func (*Int) Int64() int64 #### func (*Int) Int64() int64
> 转换为 int64 类型进行返回
*** ***
<span id="struct_Int_String"></span> <span id="struct_Int_String"></span>
#### func (*Int) String() string #### func (*Int) String() string
> 转换为 string 类型进行返回
*** ***
<span id="struct_Int_Add"></span> <span id="struct_Int_Add"></span>
#### func (*Int) Add(i *Int) *Int #### func (*Int) Add(i *Int) *Int
> 使用 i 对 slf 进行加法运算slf 的值会变为运算后的值。返回 slf
*** ***
<span id="struct_Int_AddInt"></span> <span id="struct_Int_AddInt"></span>

View File

@ -19,6 +19,8 @@
|[NewBitSet](#NewBitSet)|通过指定的 Bit 位创建一个 BitSet |[NewBitSet](#NewBitSet)|通过指定的 Bit 位创建一个 BitSet
|[TryWriteChannel](#TryWriteChannel)|尝试写入 channel如果 channel 无法写入则忽略,返回是否写入成功 |[TryWriteChannel](#TryWriteChannel)|尝试写入 channel如果 channel 无法写入则忽略,返回是否写入成功
|[TryWriteChannelByHandler](#TryWriteChannelByHandler)|尝试写入 channel如果 channel 无法写入则执行 handler |[TryWriteChannelByHandler](#TryWriteChannelByHandler)|尝试写入 channel如果 channel 无法写入则执行 handler
|[TryReadChannel](#TryReadChannel)|尝试读取 channel如果 channel 无法读取则忽略,返回是否读取成功
|[TryReadChannelByHandler](#TryReadChannelByHandler)|尝试读取 channel如果 channel 无法读取则执行 handler
|[RegError](#RegError)|通过错误码注册错误,返回错误的引用 |[RegError](#RegError)|通过错误码注册错误,返回错误的引用
|[RegErrorRef](#RegErrorRef)|通过错误码注册错误,返回错误的引用 |[RegErrorRef](#RegErrorRef)|通过错误码注册错误,返回错误的引用
|[GetError](#GetError)|通过错误引用获取错误码和真实错误信息,如果错误不存在则返回 0如果错误引用不存在则返回原本的错误 |[GetError](#GetError)|通过错误引用获取错误码和真实错误信息,如果错误不存在则返回 0如果错误引用不存在则返回原本的错误
@ -107,6 +109,50 @@
#### func NewBitSet\[Bit generic.Integer\](bits ...Bit) *BitSet[Bit] #### func NewBitSet\[Bit generic.Integer\](bits ...Bit) *BitSet[Bit]
<span id="NewBitSet"></span> <span id="NewBitSet"></span>
> 通过指定的 Bit 位创建一个 BitSet > 通过指定的 Bit 位创建一个 BitSet
> - 当指定的 Bit 位存在负数时,将会 panic
**示例代码:**
```go
func ExampleNewBitSet() {
var bs = super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9)
bs.Set(10)
fmt.Println(bs.Bits())
}
```
<details>
<summary>查看 / 收起单元测试</summary>
```go
func TestNewBitSet(t *testing.T) {
var cases = []struct {
name string
in []int
shouldPanic bool
}{{name: "normal", in: []int{1, 2, 3, 4, 5, 6, 7, 8, 9}}, {name: "empty", in: make([]int, 0)}, {name: "nil", in: nil}, {name: "negative", in: []int{-1, -2}, shouldPanic: true}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil && !c.shouldPanic {
t.Fatalf("panic: %v", r)
}
}()
bs := super.NewBitSet(c.in...)
t.Log(bs)
})
}
}
```
</details>
*** ***
#### func TryWriteChannel\[T any\](ch chan T, data T) bool #### func TryWriteChannel\[T any\](ch chan T, data T) bool
@ -120,6 +166,18 @@
> 尝试写入 channel如果 channel 无法写入则执行 handler > 尝试写入 channel如果 channel 无法写入则执行 handler
> - 无法写入的情况包括channel 已满、channel 已关闭 > - 无法写入的情况包括channel 已满、channel 已关闭
***
#### func TryReadChannel\[T any\](ch chan T) (v T, suc bool)
<span id="TryReadChannel"></span>
> 尝试读取 channel如果 channel 无法读取则忽略,返回是否读取成功
> - 无法读取的情况包括channel 已空、channel 已关闭
***
#### func TryReadChannelByHandler\[T any\](ch chan T, handler func (ch chan T) T) (v T)
<span id="TryReadChannelByHandler"></span>
> 尝试读取 channel如果 channel 无法读取则执行 handler
> - 无法读取的情况包括channel 已空、channel 已关闭
*** ***
#### func RegError(code int, message string) error #### func RegError(code int, message string) error
<span id="RegError"></span> <span id="RegError"></span>
@ -757,6 +815,18 @@ type BitSet[Bit generic.Integer] struct {
#### func (*BitSet) Set(bit Bit) *BitSet[Bit] #### func (*BitSet) Set(bit Bit) *BitSet[Bit]
> 将指定的位 bit 设置为 1 > 将指定的位 bit 设置为 1
**示例代码:**
```go
func ExampleBitSet_Set() {
var bs = super.NewBitSet[int]()
bs.Set(10)
fmt.Println(bs.Bits())
}
```
<details> <details>
<summary>查看 / 收起单元测试</summary> <summary>查看 / 收起单元测试</summary>
@ -764,11 +834,29 @@ type BitSet[Bit generic.Integer] struct {
```go ```go
func TestBitSet_Set(t *testing.T) { func TestBitSet_Set(t *testing.T) {
bs := super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) var cases = []struct {
bs.Set(11) name string
bs.Set(12) in []int
bs.Set(13) shouldPanic bool
t.Log(bs) }{{name: "normal", in: []int{1, 2, 3, 4, 5, 6, 7, 8, 9}}, {name: "empty", in: make([]int, 0)}, {name: "nil", in: nil}, {name: "negative", in: []int{-1, -2}, shouldPanic: true}}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil && !c.shouldPanic {
t.Fatalf("panic: %v", r)
}
}()
bs := super.NewBitSet[int]()
for _, bit := range c.in {
bs.Set(bit)
}
for _, bit := range c.in {
if !bs.Has(bit) {
t.Fatalf("bit %v not set", bit)
}
}
})
}
} }
``` ```
@ -783,6 +871,18 @@ func TestBitSet_Set(t *testing.T) {
#### func (*BitSet) Del(bit Bit) *BitSet[Bit] #### func (*BitSet) Del(bit Bit) *BitSet[Bit]
> 将指定的位 bit 设置为 0 > 将指定的位 bit 设置为 0
**示例代码:**
```go
func ExampleBitSet_Del() {
var bs = super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9)
bs.Del(1)
fmt.Println(bs.Bits())
}
```
<details> <details>
<summary>查看 / 收起单元测试</summary> <summary>查看 / 收起单元测试</summary>
@ -790,12 +890,32 @@ func TestBitSet_Set(t *testing.T) {
```go ```go
func TestBitSet_Del(t *testing.T) { func TestBitSet_Del(t *testing.T) {
bs := super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) var cases = []struct {
bs.Del(11) name string
bs.Del(12) in []int
bs.Del(13) shouldPanic bool
bs.Del(10) }{{name: "normal", in: []int{1, 2, 3, 4, 5, 6, 7, 8, 9}}, {name: "empty", in: make([]int, 0)}, {name: "nil", in: nil}, {name: "negative", in: []int{-1, -2}, shouldPanic: true}}
t.Log(bs) for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil && !c.shouldPanic {
t.Fatalf("panic: %v", r)
}
}()
bs := super.NewBitSet[int]()
for _, bit := range c.in {
bs.Set(bit)
}
for _, bit := range c.in {
bs.Del(bit)
}
for _, bit := range c.in {
if bs.Has(bit) {
t.Fatalf("bit %v not del", bit)
}
}
})
}
} }
``` ```
@ -811,6 +931,21 @@ func TestBitSet_Del(t *testing.T) {
> 将 BitSet 中的比特位集合缩小到最小 > 将 BitSet 中的比特位集合缩小到最小
> - 正常情况下当 BitSet 中的比特位超出 64 位时,将自动增长,当 BitSet 中的比特位数量减少时,可以使用该方法将 BitSet 中的比特位集合缩小到最小 > - 正常情况下当 BitSet 中的比特位超出 64 位时,将自动增长,当 BitSet 中的比特位数量减少时,可以使用该方法将 BitSet 中的比特位集合缩小到最小
**示例代码:**
```go
func ExampleBitSet_Shrink() {
var bs = super.NewBitSet(111, 222, 333, 444)
fmt.Println(bs.Cap())
bs.Del(444)
fmt.Println(bs.Cap())
bs.Shrink()
fmt.Println(bs.Cap())
}
```
<details> <details>
<summary>查看 / 收起单元测试</summary> <summary>查看 / 收起单元测试</summary>
@ -818,13 +953,22 @@ func TestBitSet_Del(t *testing.T) {
```go ```go
func TestBitSet_Shrink(t *testing.T) { func TestBitSet_Shrink(t *testing.T) {
bs := super.NewBitSet(63) var cases = []struct {
t.Log(bs.Cap()) name string
bs.Set(200) in []int
t.Log(bs.Cap()) }{{name: "normal", in: []int{1, 2, 3, 4, 5, 6, 7, 8, 9}}, {name: "empty", in: make([]int, 0)}, {name: "nil", in: nil}}
bs.Del(200) for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
bs := super.NewBitSet(c.in...)
for _, v := range c.in {
bs.Del(v)
}
bs.Shrink() bs.Shrink()
t.Log(bs.Cap()) if bs.Cap() != 0 {
t.Fatalf("cap %v != 0", bs.Cap())
}
})
}
} }
``` ```
@ -839,24 +983,70 @@ func TestBitSet_Shrink(t *testing.T) {
#### func (*BitSet) Cap() int #### func (*BitSet) Cap() int
> 返回当前 BitSet 中可以表示的最大比特位数量 > 返回当前 BitSet 中可以表示的最大比特位数量
**示例代码:**
```go
func ExampleBitSet_Cap() {
var bs = super.NewBitSet(63)
fmt.Println(bs.Cap())
}
```
*** ***
<span id="struct_BitSet_Has"></span> <span id="struct_BitSet_Has"></span>
#### func (*BitSet) Has(bit Bit) bool #### func (*BitSet) Has(bit Bit) bool
> 检查指定的位 bit 是否被设置为 1 > 检查指定的位 bit 是否被设置为 1
**示例代码:**
```go
func ExampleBitSet_Has() {
var bs = super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9)
fmt.Println(bs.Has(1))
fmt.Println(bs.Has(10))
}
```
*** ***
<span id="struct_BitSet_Clear"></span> <span id="struct_BitSet_Clear"></span>
#### func (*BitSet) Clear() *BitSet[Bit] #### func (*BitSet) Clear() *BitSet[Bit]
> 清空所有的比特位 > 清空所有的比特位
**示例代码:**
```go
func ExampleBitSet_Clear() {
var bs = super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9)
bs.Clear()
fmt.Println(bs.Bits())
}
```
*** ***
<span id="struct_BitSet_Len"></span> <span id="struct_BitSet_Len"></span>
#### func (*BitSet) Len() int #### func (*BitSet) Len() int
> 返回当前 BitSet 中被设置的比特位数量 > 返回当前 BitSet 中被设置的比特位数量
**示例代码:**
```go
func ExampleBitSet_Len() {
var bs = super.NewBitSet(1, 2, 3, 4, 5, 6, 7, 8, 9)
fmt.Println(bs.Len())
}
```
*** ***
<span id="struct_BitSet_Bits"></span> <span id="struct_BitSet_Bits"></span>