Compare commits

..
2 Commits
Author SHA1 Message Date
dudaodong e95d7c82cd doc: update doc for function package 2024-03-04 10:19:39 +08:00
donutloopandGitHub e138043289 Function: AcceptIf (#198)
AcceptIf returns another function of the same signature as the apply function but also includes a bool value to indicate success or failure.
A predicate function that takes an argument of type T and returns a bool.
An apply function that also takes an argument of type T and returns a modified value of the same type.
2024-03-04 10:00:43 +08:00
7 changed files with 246 additions and 1 deletions
+15 -1
View File
@@ -791,11 +791,25 @@ import "github.com/duke-git/lancet/v2/function"
[[play](https://go.dev/play/p/hbON-Xeyn5N)]
- **<big>Pipeline</big>** : takes a list of functions and returns a function whose param will be passed into the functions one by one.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Pipeline)]
[[play](https://go.dev/play/p/mPdUVvj6HD6)]
- **<big>AcceptIf</big>** : returns another function of the same signature as the apply function but also includes a bool value to indicate success or failure.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#AcceptIf)]
- **<big>And</big>** : returns a composed predicate that represents the logical AND of a list of predicates.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#And)]
- **<big>Or</big>** : returns a composed predicate that represents the logical OR of a list of predicates.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Or)]
- **<big>Negate</big>** : returns a predicate that represents the logical negation of this predicate.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Negate)]
- **<big>Nor</big>** : returns a composed predicate that represents the logical NOR of a list of predicates.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Nor)]
- **<big>Nand</big>** : returns a composed predicate that represents the logical Nand of a list of predicates.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Nand)]
- **<big>Xnor</big>** : returns a composed predicate that represents the logical XNOR of a list of predicates.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Xnor)]
- **<big>Watcher</big>** : Watcher is used for record code execution time. can start/stop/reset the watch timer. get the elapsed time of function execution.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Watcher)]
[[play](https://go.dev/play/p/l2yrOpCLd1I)]
<h3 id="maputil"> 12. Maputil package includes some functions to manipulate map.&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
+14
View File
@@ -790,6 +790,20 @@ import "github.com/duke-git/lancet/v2/function"
- **<big>Pipeline</big>** : 从右至左执行函数列表。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/function.md#Pipeline)]
[[play](https://go.dev/play/p/mPdUVvj6HD6)]
- **<big>AcceptIf</big>** : AcceptIf函数会返回另一个函数,该函数的签名与apply函数相同,但同时还会包含一个布尔值来表示成功或失败。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/function.md#AcceptIf)]
- **<big>And</big>** : 返回一个复合谓词判断函数,该判断函数表示一组谓词的逻辑and操作。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/function.md#And)]
- **<big>Or</big>** : 返回一个复合谓词判断函数,该判断函数表示一组谓词的逻辑or操作。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/function.md#Or)]
- **<big>Negate</big>** : 返回一个谓词函数,该谓词函数表示当前谓词的逻辑否定。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/function.md#Negate)]
- **<big>Nor</big>** : 返回一个复合谓词判断函数,该判断函数表示一组谓词的逻辑非或nor的操作。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/function.md#Nor)]
- **<big>Nand</big>** : 返回一个复合谓词判断函数,该判断函数表示一组谓词的逻辑非与nand的操作。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/function.md#Nand)]
- **<big>Xnor</big>** : 返回一个复合谓词判断函数,该判断函数表示一组谓词的逻辑异或xnor的操作。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/function.md#Xnor)]
- **<big>Watcher</big>** : Watcher 用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/function.md#Watcher)]
[[play](https://go.dev/play/p/l2yrOpCLd1I)]
+53
View File
@@ -39,6 +39,8 @@ import (
- [Nor](#Nor)
- [Xnor](#Xnor)
- [Nand](#Nand)
- [AcceptIf](#AcceptIf)
<div STYLE="page-break-after: always;"></div>
@@ -638,4 +640,55 @@ func main() {
// true
// false
}
```
### <span id="AcceptIf">AcceptIf</span>
<p>AcceptIf函数会返回另一个函数,该函数的签名与 apply 函数相同,但同时还会包含一个布尔值来表示成功或失败。</p>
<b>函数签名:</b>
```go
func AcceptIf[T any](predicate func(T) bool, apply func(T) T) func(T) (T, bool)
```
<b>示例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/function"
)
func main() {
adder := AcceptIf(
And(
func(x int) bool {
return x > 10
}, func(x int) bool {
return x%2 == 0
}),
func(x int) int {
return x + 1
},
)
result, ok := adder(20)
fmt.Println(result)
fmt.Println(ok)
result, ok = adder(21)
fmt.Println(result)
fmt.Println(ok)
// Output:
// 21
// true
// 0
// false
}
```
+54
View File
@@ -39,6 +39,7 @@ import (
- [Nor](#Nor)
- [Xnor](#Xnor)
- [Nand](#Nand)
- [AcceptIf](#AcceptIf)
<div STYLE="page-break-after: always;"></div>
@@ -638,4 +639,57 @@ func main() {
// true
// false
}
```
### <span id="AcceptIf">AcceptIf</span>
<p>AcceptIf returns another function of the same signature as the apply function but also includes a bool value to indicate success or failure.
A predicate function that takes an argument of type T and returns a bool.
An apply function that also takes an argument of type T and returns a modified value of the same type.</p>
<b>Signature:</b>
```go
func AcceptIf[T any](predicate func(T) bool, apply func(T) T) func(T) (T, bool)
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/function"
)
func main() {
adder := AcceptIf(
And(
func(x int) bool {
return x > 10
}, func(x int) bool {
return x%2 == 0
}),
func(x int) int {
return x + 1
},
)
result, ok := adder(20)
fmt.Println(result)
fmt.Println(ok)
result, ok = adder(21)
fmt.Println(result)
fmt.Println(ok)
// Output:
// 21
// true
// 0
// false
}
```
+21
View File
@@ -136,6 +136,27 @@ func Pipeline[T any](funcs ...func(T) T) func(T) T {
}
}
// AcceptIf returns another function of the same signature as the apply function but also includes a bool value to indicate success or failure.
// A predicate function that takes an argument of type T and returns a bool.
// An apply function that also takes an argument of type T and returns a modified value of the same type.
func AcceptIf[T any](predicate func(T) bool, apply func(T) T) func(T) (T, bool) {
if predicate == nil {
panic("programming error: predicate must be not nil")
}
if apply == nil {
panic("programming error: apply must be not nil")
}
return func(t T) (T, bool) {
if !predicate(t) {
var defaultValue T
return defaultValue, false
}
return apply(t), true
}
}
func unsafeInvokeFunc(fn any, args ...any) []reflect.Value {
fv := reflect.ValueOf(fn)
params := make([]reflect.Value, len(args))
+29
View File
@@ -145,3 +145,32 @@ func ExamplePipeline() {
// Output:
// 36
}
func ExampleAcceptIf() {
adder := AcceptIf(
And(
func(x int) bool {
return x > 10
}, func(x int) bool {
return x%2 == 0
}),
func(x int) int {
return x + 1
},
)
result, ok := adder(20)
fmt.Println(result)
fmt.Println(ok)
result, ok = adder(21)
fmt.Println(result)
fmt.Println(ok)
// Output:
// 21
// true
// 0
// false
}
+60
View File
@@ -162,3 +162,63 @@ func TestPipeline(t *testing.T) {
assert.Equal(36, f(2))
}
func TestAcceptIf(t *testing.T) {
assert := internal.NewAssert(t, "AcceptIf")
adder := AcceptIf(
And(
func(x int) bool {
return x > 10
}, func(x int) bool {
return x%2 == 0
}),
func(x int) int {
return x + 1
},
)
result, ok := adder(20)
assert.Equal(21, result)
assert.Equal(true, ok)
result, ok = adder(21)
assert.Equal(0, result)
assert.Equal(false, ok)
}
func TestAcceptIfPanicMissingPredicate(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestAcceptIfPanicMissingPredicate")
defer func() {
v := recover()
assert.Equal("programming error: predicate must be not nil", v)
}()
AcceptIf(
nil,
func(x int) int {
return x
},
)
}
func TestAcceptIfPanicMissingApply(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestAcceptIfPanicMissingApply")
defer func() {
v := recover()
assert.Equal("programming error: apply must be not nil", v)
}()
AcceptIf(
func(i int) bool {
return false
},
nil,
)
}