Skip to content

Commit

Permalink
增加新的逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
yangyile committed Nov 25, 2024
1 parent d57eef9 commit 13757e6
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 2 deletions.
182 changes: 180 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ The `tern` package provides the following functions based on condition types and
| `FFV` | `func() bool` | Function returning value | Direct value |
| `FFF` | `func() bool` | Function returning value | Function returning value |

Additionally, utility functions like `BV`, `BF`, `FV`, and `FF` simplify zero-value fallbacks.

### Lazy Evaluation Example

Using deferred execution ensures unnecessary computations are avoided:
Expand Down Expand Up @@ -104,6 +102,186 @@ func main() {
}
```

以下是对 `BV``BF``FV``FF` 函数的详细表格说明:

---

### Utility Functions for Zero-Value Fallbacks

| **Function** | **Condition Type** | **Primary Value** | **Fallback Value** | **Description** |
|--------------|--------------------|--------------------------|------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
| `BV` | `bool` | Direct value | Zero value of type `T` | Returns the first value if the condition is true, otherwise returns the zero value of type `T`. |
| `BF` | `bool` | Function returning value | Zero value of type `T` | Evaluates the function only if the condition is true, otherwise returns the zero value of type `T`. |
| `FV` | `func() bool` | Direct value | Zero value of type `T` | Evaluates the condition function and returns the first value if true, otherwise returns the zero value of type `T`. |
| `FF` | `func() bool` | Function returning value | Zero value of type `T` | Evaluates the condition function and returns the result of the first function if true, otherwise returns the zero value of type `T`. |

---

### Examples

#### Using `BV`

```go
result := tern.BV(false, "value")
// Output: (empty string, as the condition is false)
```

#### Using `BF`

```go
result := tern.BF(false, func() string { return "value" })
// Output: (empty string, as the condition is false)
```

#### Using `FV`

```go
condition := func() bool { return true }
result := tern.FV(condition, "value")
// Output: "value" (as the condition function returns true)
```

#### Using `FF`

```go
condition := func() bool { return false }
result := tern.FF(condition, func() string { return "value" })
// Output: (empty string, as the condition function returns false)
```

---

### Additional Utility Functions in `terngo` Package

The `terngo` subpackage extends the functionality of `tern` with additional utility functions, specifically designed for comparing values to their zero value. These functions allow for more expressive handling of default values when one of the inputs might be zero.

| **Function** | **Comparison Type** | **Primary Value** | **Fallback Value** | **Description** |
|--------------|---------------------|-------------------|--------------------------|---------------------------------------------------------------------------------------------------------------------------------------|
| `VV` | Direct comparison | Direct value | Direct value | Returns the first value if it is not the zero value of type `T`, otherwise returns the second value. |
| `VF` | Direct comparison | Direct value | Function returning value | Returns the first value if it is not the zero value of type `T`, otherwise evaluates and returns the result of the fallback function. |

---

### Examples

#### Using `VV`

```go
package main

import (
"fmt"
"github.com/yyle88/tern/terngo"
)

func main() {
result := terngo.VV("non-zero", "fallback")
fmt.Println(result) // Output: "non-zero"

result = terngo.VV("", "fallback")
fmt.Println(result) // Output: "fallback"
}
```

#### Using `VF`

```go
package main

import (
"fmt"
"github.com/yyle88/tern/terngo"
)

func main() {
fallbackFunc := func() string { return "fallback from func" }

result := terngo.VF("non-zero", fallbackFunc)
fmt.Println(result) // Output: "non-zero"

result = terngo.VF("", fallbackFunc)
fmt.Println(result) // Output: "fallback from func"
}
```

---

### Key Benefits of `VV` and `VF`

- **Zero-Value Handling**: These functions leverage `tern.Zero[T]()` to check if the primary value is a zero value.
- **Fallback Options**: `VF` provides flexibility by allowing dynamic evaluation of the fallback value through a function.

---

By including these functions in the `terngo` package, developers gain even more expressive tools to simplify conditional logic in Go.

### Additional Utility Functions for Pointer Modification in `terngo`

The `terngo` subpackage introduces `PV` and `PF`, two specialized functions for safely modifying a pointer's value when it holds the zero value of its type. These functions ensure safer and more expressive manipulation of pointers while providing fallback options.

| **Function** | **Pointer Check** | **Fallback Value** | **Description** |
|--------------|-------------------------|--------------------------|---------------------------------------------------------------------------------------------------------------------------------------|
| `PV` | Pointer to direct value | Direct value | Sets the pointed-to value to the fallback value if it is the zero value of type `T`. Panics if the pointer is `nil`. |
| `PF` | Pointer to direct value | Function returning value | Sets the pointed-to value to the result of the fallback function if it is the zero value of type `T`. Panics if the pointer is `nil`. |

---

### Examples

#### Using `PV`

```go
package main

import (
"fmt"
"github.com/yyle88/tern/terngo"
)

func main() {
var value int
terngo.PV(&value, 42)
fmt.Println(value) // Output: 42

value = 7
terngo.PV(&value, 99)
fmt.Println(value) // Output: 7
}
```

#### Using `PF`

```go
package main

import (
"fmt"
"github.com/yyle88/tern/terngo"
)

func main() {
var value int
fallbackFunc := func() int { return 42 }

terngo.PF(&value, fallbackFunc)
fmt.Println(value) // Output: 42

value = 7
terngo.PF(&value, fallbackFunc)
fmt.Println(value) // Output: 7
}
```

---

### Key Features of `PV` and `PF`

- **Pointer Safety**: These functions panic if the provided pointer is `nil`, ensuring reliable execution.
- **Zero-Value Check**: Use `tern.Zero[T]()` to determine whether the current value is the zero value of its type.
- **Dynamic Fallback**: `PF` allows for fallback values to be generated dynamically via a function.

By leveraging `PV` and `PF`, developers can seamlessly handle zero-value assignments for pointer-based logic, maintaining both clarity and robustness in their Go code.

## Why Use `tern`?

1. **Readability**: Simplifies conditional logic, making the code easier to follow.
Expand Down
17 changes: 17 additions & 0 deletions terngo/znew.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package terngo

import "github.com/yyle88/tern"

func VV[T comparable](a T, b T) T {
if a != tern.Zero[T]() {
return a
}
return b
}

func VF[T comparable](a T, b func() T) T {
if a != tern.Zero[T]() {
return a
}
return b()
}
30 changes: 30 additions & 0 deletions terngo/znew_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package terngo_test

import (
"testing"

"github.com/stretchr/testify/require"
"github.com/yyle88/tern/terngo"
)

func TestVV(t *testing.T) {
require.Equal(t, 1, terngo.VV(0, 1))
require.Equal(t, 1, terngo.VV(1, 2))
require.Equal(t, "a", terngo.VV("", "a"))
require.Equal(t, "a", terngo.VV("a", "b"))
}

func TestVF(t *testing.T) {
require.Equal(t, 1, terngo.VF(0, func() int {
return 1
}))
require.Equal(t, 1, terngo.VF(1, func() int {
return 2
}))
require.Equal(t, "a", terngo.VF("", func() string {
return "a"
}))
require.Equal(t, "a", terngo.VF("a", func() string {
return "b"
}))
}
15 changes: 15 additions & 0 deletions terngo/zset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package terngo

import "github.com/yyle88/tern"

func PV[T comparable](p *T, b T) {
if *p == tern.Zero[T]() {
*p = b
}
}

func PF[T comparable](p *T, b func() T) {
if *p == tern.Zero[T]() {
*p = b()
}
}
52 changes: 52 additions & 0 deletions terngo/zset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package terngo_test

import (
"testing"

"github.com/stretchr/testify/require"
"github.com/yyle88/tern/terngo"
)

func TestPV(t *testing.T) {
a := 0
terngo.PV(&a, 1)
require.Equal(t, 1, a)

b := 1
terngo.PV(&b, 2)
require.Equal(t, 1, b)

c := ""
terngo.PV(&c, "a")
require.Equal(t, "a", c)

s := "a"
terngo.PV(&s, "b")
require.Equal(t, "a", s)
}

func TestPF(t *testing.T) {
a := 0
terngo.PF(&a, func() int {
return 1
})
require.Equal(t, 1, a)

b := 1
terngo.PF(&b, func() int {
return 2
})
require.Equal(t, 1, b)

c := ""
terngo.PF(&c, func() string {
return "a"
})
require.Equal(t, "a", c)

s := "a"
terngo.PF(&s, func() string {
return "b"
})
require.Equal(t, "a", s)
}

0 comments on commit 13757e6

Please sign in to comment.