Golang条件检查包Check的使用指南

Golang条件检查包Check的使用指南 大家好,

我最近发布了一个新的 Go 包 checkcheck package - github.com/nyggus/check - pkg.go.dev。这个包使你能够检查多种类型的切片和映射的各种条件,包括它们的比较。该包并不专门针对测试,因为很多时候你需要比较两个切片或映射,或者检查一个值是否在切片或映射中,切片是否唯一等等。当然,这些函数在测试中也经常很有用——包括内置的 testing 模块。实际上,我认为它并不违背 testing 的假设;它只会让一些比较变得更简单。

你可以在包的 README、包含示例的文档文件以及文档本身中找到很多示例(所有函数都有经过测试的示例覆盖;整个包具有完整的测试覆盖率)。

这里有几个例子,展示你可以用它做什么:

IsUniqueIntSlice([]int{55, 55, 56}) // false
IsUniqueMapStringString(
    map[string]string{"key1": "a", "key2": "a", "key3": "Q"},
) // false

(对于映射,唯一性指的是映射值的唯一性,忽略键。)

浮点数使用 Epsilon 进行比较,它提供了比较的精度(小于 Epsilon 的差异被视为 0):

keys, ok := IsValueInMapStringFloat64(
    .01,
    map[string]float64{"a": .011, "b": .02, "c": .02},
    0,
) // [] false
keys, ok = IsValueInMapStringFloat64(
    .01,
    map[string]float64{"a": .011, "b": .02, "c": .02},
    0.1,
) // true [a b]

(上面,keys 是找到该值的那些键。)

AreEqualMapsStringInt(
	map[string]int{"1": 1, "2": 100, "3": 1},
	map[string]int{"1": 1, "3": 1, "2": 100},
) // true
AllKeyValuePairsInMapIntInt(
    map[int]int{1: 1, 3: 3},
    map[int]int{1: 1, 2: 2, 3: 3},
) // true
AnyKeyValuePairsInMapIntInt(
    map[int]int{1: 1, 4: 4},
    map[int]int{1: 1, 2: 2, 3: 3},
) // true
AreEqualSlicesString(
    []string{"a", "a", "b"},
    []string{"a", "b", "a"},
) // false - 虽然值相同,但它们的顺序不同
AreEqualSortedSlicesString(
    []string{"a", "a", "b"},
    []string{"a", "b", "a"},
) // true - 这个函数首先对切片进行排序,然后比较它们,因此忽略顺序
values, ok := WhichValuesInStringSlice(
    []string{"10", "Shout Bamalama!", "Something else"},
    []string{"10", "Shout Bamalama!", "50", "This and nothing", "Guess what", "10"},
) // true map[10:[0 5] Shout Bamalama!:[1]]

该包提供了许多这样的函数来检查条件。由于它提供了检查切片(或映射)是否具有唯一值(没有重复值)的功能,我决定也添加相应的函数来生成唯一切片(不是映射,因为映射由于键不同而无法变得唯一),例如:

UniqueStringSlice([]string{"a", "b", "a"}) // [a b]
UniqueIntSlice([]int{1, 1, 3, 3, 12, 1, 1, 12, 1}) // [1 3 12]

我将非常感谢任何评论,你可以在这里或在仓库中(通过 issues)分享。我想有些东西可以用不同的方式或更好的方式编码。我也想象有些开发者可能更喜欢自己编写每个这样的检查——但这个包就是为了帮助他们,使代码更短、更简单、更容易理解。但是,如果你发现任何错误或不正确的地方,请告诉我,我很乐意进行改进。

我希望至少你们中的一些人会觉得这个包有用。它并没有提供任何真正复杂的东西,它所提供的一切都可以轻松编码——但你可以使用一个函数来代替 5-10 行代码,这个函数的名字清楚地说明了正在做什么。简单性是我所追求的,希望我做到了这一点。

如果你喜欢这个包,请在 github 上给它一个星标。如果你想贡献,请随时参与!


更多关于Golang条件检查包Check的使用指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang条件检查包Check的使用指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


check 包为 Go 开发者提供了简洁的切片和映射条件检查功能,以下是一些典型使用场景的示例:

1. 唯一性检查

// 检查切片值是否唯一
fmt.Println(check.IsUniqueIntSlice([]int{1, 2, 3, 2})) // false
fmt.Println(check.IsUniqueStringSlice([]string{"a", "b", "c"})) // true

// 检查映射值是否唯一
m := map[string]int{"x": 1, "y": 2, "z": 1}
fmt.Println(check.IsUniqueMapStringInt(m)) // false

2. 浮点数比较(带精度控制)

// 使用默认 Epsilon (1e-9)
fmt.Println(check.AreEqualFloat64Slices(
    []float64{0.1 + 0.2, 1.0/3.0},
    []float64{0.3, 0.3333333333333333},
)) // true

// 自定义精度
fmt.Println(check.AreEqualFloat64SlicesWithEpsilon(
    []float64{1.001, 2.002},
    []float64{1.002, 2.003},
    0.01,
)) // true

3. 映射包含关系检查

subMap := map[int]string{1: "a", 3: "c"}
superMap := map[int]string{1: "a", 2: "b", 3: "c", 4: "d"}

// 检查所有键值对是否都在目标映射中
fmt.Println(check.AllKeyValuePairsInMapIntString(subMap, superMap)) // true

// 检查至少一个键值对在目标映射中
partialMap := map[int]string{5: "e", 3: "c"}
fmt.Println(check.AnyKeyValuePairsInMapIntString(partialMap, superMap)) // true

4. 值查找功能

// 在映射中查找值
keys, found := check.IsValueInMapStringInt(
    42,
    map[string]int{"a": 10, "b": 42, "c": 42, "d": 30},
)
// found=true, keys=["b", "c"]

// 在切片中查找多个值
indices, found := check.WhichValuesInIntSlice(
    []int{10, 20},
    []int{5, 10, 15, 20, 10, 25},
)
// found=true, indices=map[10:[0 4] 20:[3]]

5. 集合操作辅助

// 生成唯一切片
fmt.Println(check.UniqueIntSlice([]int{1, 2, 2, 3, 1, 4})) // [1 2 3 4]

// 有序比较
slice1 := []string{"b", "a", "c"}
slice2 := []string{"c", "a", "b"}
fmt.Println(check.AreEqualSlicesString(slice1, slice2)) // false
fmt.Println(check.AreEqualSortedSlicesString(slice1, slice2)) // true

6. 测试场景应用

func TestProcessData(t *testing.T) {
    result := processData(input)
    
    // 检查结果映射是否相等(忽略键顺序)
    expected := map[string]float64{"x": 1.5, "y": 2.3}
    if !check.AreEqualMapsStringFloat64(result, expected) {
        t.Errorf("结果不匹配: got %v, want %v", result, expected)
    }
    
    // 检查切片内容(忽略顺序)
    expectedSlice := []int{1, 2, 3, 4}
    if !check.AreEqualSortedSlicesInt(resultSlice, expectedSlice) {
        t.Errorf("切片不匹配")
    }
}

7. 嵌套结构检查

// 检查映射的映射
map1 := map[string]map[int]bool{
    "a": {1: true, 2: false},
    "b": {3: true},
}
map2 := map[string]map[int]bool{
    "b": {3: true},
    "a": {2: false, 1: true},
}
fmt.Println(check.AreEqualMapsStringMapIntBool(map1, map2)) // true

该包通过类型明确的函数签名(如 IsUniqueMapStringIntAreEqualSlicesFloat64)提供了编译时类型安全。对于需要频繁进行集合比较的业务逻辑和数据验证场景,这些函数能显著减少样板代码。

回到顶部