在 Go 1.18 中使用泛型检查回文

在阅读了几篇关于 Go 1.18 中泛型的文章和视频之后,我对使用它创建一个可以接受字符串和整数的回文检查函数产生了兴趣。

首先,我创建了一个名为 palindrome 的新项目和一个新包(也称为 palindrome)。然后我创建了一个名为 signedOrString的约束 ,它可以接收带符号的(int、int8、int16、int32 和int64)或字符串。此外,我创建了一个函数来检查它是否是回文。

type signedOrString interface{
	constraints.Signed | string
}

func palindrome[input signedOrString](sliceInput []input) bool {
	length := len(sliceInput)
	for i:=0;i<length/2;i++{
		if sliceInput[i] != sliceInput[length-1-i] {
			return false
		}
	}
	return true
}

这是一个非常好的功能,因为我们不必重新创建对每种数据类型执行相同操作的函数。

然后我想升级功能,直接从单词或数字中检查回文,而不是从切片中。我再次尝试使用泛型功能,但这次被绊倒了,因为当我们将类型字符串输入函数时,我们可以使用内置的拆分函数将其转换为切片,而将整数类型转换为切片我们需要创建自己的函数.

我们如何区分字符串和带符号(整数)之间的流?

我想出了一个想法,将其转换为 interface{} 类型,然后将流与 switch 函数分开。让我们看一下代码。

func IsPalindrome[input signedOrString](firstInput input) bool {
	return func(toInterface interface{}) bool {
		var sliceInt []int
		switch newType := toInterface.(type){
			case string:
				return palindrome(strings.Split(newType, ""))
			case int:
				sliceInt = sliceInteger(newType)
			case int8:
				sliceInt = sliceInteger(newType)
			case int16:
				sliceInt = sliceInteger(newType)
			case int32:
				sliceInt = sliceInteger(newType)
			case int64:
				sliceInt = sliceInteger(newType)
		}
		return palindrome(sliceInt)
	}(firstInput)
}

func sliceInteger[signed constraints.Signed](input signed) (slice []int) {
	for input > 0 {
		slice = append(slice, int(input%10))
		input/=10
	}
	return
}

将任何有符号(整数)值转换为切片整数的sliceInteger函数 仍然是使用泛型的一个好习惯,但对于 IsPalindrome函数,我认为泛型不是为完成此类工作而构建的。

之后,我们可以从 main.go 中调用 IsPalindrome 函数并检查输入变量是否为回文。

package main

import (
	"fmt"
	"palindrome/palindrome"
)

func main() {
	fmt.Println(palindrome.IsPalindrome("AAAB")) // false
	fmt.Println(palindrome.IsPalindrome("ABABA")) // true
	fmt.Println(palindrome.IsPalindrome(10001)) // true
	fmt.Println(palindrome.IsPalindrome(10110)) // false
}

结论

Go 1.18 泛型适用于构建具有完全相同流程的函数,无论输入类型如何,例如上面的 回文 和 sliceInteger函数。


对于IsPalindrome 函数 – 调用此函数的其他开发人员认为它只能使用字符串或有符号(整数)类型输入。

我希望你们中的一些人觉得这很有帮助。如果您有兴趣查看所有源代码,可以在 https://github.com/yudaph/palindrome.

谢谢!