Golang泛型编程教程 - 代码报错问题解析
Golang泛型编程教程 - 代码报错问题解析 出于好奇……我运行了下面的代码,它来自 https://go.dev/doc/tutorial/generics 的教程,但在调用泛型函数的代码处遇到了错误,提示意外的逗号,预期是冒号。
注意:
- 在 Go Playground 中运行此代码时,没有问题。
- 是的,我运行的是他们要求的测试版。
- 这不是我的代码。
package main
import "fmt"
type Number interface {
int64 | float64
}
func main() {
// Initialize a map for the integer values
ints := map[string]int64{
"first": 34,
"second": 12,
}
// Initialize a map for the float values
floats := map[string]float64{
"first": 35.98,
"second": 26.99,
}
fmt.Printf("Non-Generic Sums: %v and %v\n",
SumInts(ints),
SumFloats(floats))
fmt.Printf("Generic Sums: %v and %v\n",
SumIntsOrFloats[string, int64](ints),
SumIntsOrFloats[string, float64](floats))
fmt.Printf("Generic Sums, type parameters inferred: %v and %v\n",
SumIntsOrFloats(ints),
SumIntsOrFloats(floats))
fmt.Printf("Generic Sums with Constraint: %v and %v\n",
SumNumbers(ints),
SumNumbers(floats))
}
// SumInts adds together the values of m.
func SumInts(m map[string]int64) int64 {
var s int64
for _, v := range m {
s += v
}
return s
}
// SumFloats adds together the values of m.
func SumFloats(m map[string]float64) float64 {
var s float64
for _, v := range m {
s += v
}
return s
}
// SumIntsOrFloats sums the values of map m. It supports both floats and integers
// as map values.
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
// SumNumbers sums the values of map m. Its supports both integers
// and floats as map values.
func SumNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
更多关于Golang泛型编程教程 - 代码报错问题解析的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我之前从未注意到这一点。
你能分享一下完整的错误信息以及你的 Go 版本吗?
在这里可以运行…(通过 Goland 或命令行运行)…
playground 的版本是 1.17.6,而不是 1.18beta。
是的。 你可以将 Playground 切换到“Go 开发分支”。
我正在按照说明运行 go1.18beta1。稍后我会提供确切的代码。我目前不在。
出现的错误是
syntax error: unexpected comma, expecting :
代码是从上面的链接复制的,并通过 Mac 终端粘贴到 nano 中。我很好奇,如果其他人将其复制并粘贴到文本编辑器中,而不是使用 Go playground,是否也会收到相同的错误。
Box-O-Rocks:
import "fmt"
type Number interface {
int64 | float64
}
func main() {
// 初始化一个用于整数值的映射
ints := map[string]int64{
"first": 34,
"second": 12,
}
// 初始化一个用于浮点数值的映射
floats := map[string]float64{
"first": 35.98,
"second": 26.99,
}
fmt.Printf("非泛型求和: %v 和 %v\n",
SumInts(ints),
SumFloats(floats))
fmt.Printf("泛型求和: %v 和 %v\n",
SumIntsOrFloats[string, int64](ints),
SumIntsOrFloats[string, float64](floats))
fmt.Printf("泛型求和,类型参数推断: %v 和 %v\n",
SumIntsOrFloats(ints),
SumIntsOrFloats(floats))
fmt.Printf("带约束的泛型求和: %v 和 %v\n",
SumNumbers(ints),
SumNumbers(floats))
}
// SumInts 将映射 m 中的值相加。
func SumInts(m map[string]int64) int64 {
var s int64
for _, v := range m {
s += v
}
return s
}
// SumFloats 将映射 m 中的值相加。
func SumFloats(m map[string]float64) float64 {
var s float64
for _, v := range m {
s += v
}
return s
}
// SumIntsOrFloats 对映射 m 的值求和。它同时支持浮点数和整数作为映射值。
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
// SumNumbers 对映射 m 的值求和。它同时支持整数和浮点数作为映射值。
func SumNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
在 go1.18beta1 和 Goland 中也能运行。
import "fmt"
type Number interface {
int64 | float64
}
func main() {
// 初始化一个用于整数值的映射
ints := map[string]int64{
"first": 34,
"second": 12,
}
// 初始化一个用于浮点数值的映射
floats := map[string]float64{
"first": 35.98,
"second": 26.99,
}
fmt.Printf("非泛型求和: %v 和 %v\n",
SumInts(ints),
SumFloats(floats))
fmt.Printf("泛型求和: %v 和 %v\n",
SumIntsOrFloats[string, int64](ints),
SumIntsOrFloats[string, float64](floats))
fmt.Printf("泛型求和,类型参数已推断: %v 和 %v\n",
SumIntsOrFloats(ints),
SumIntsOrFloats(floats))
fmt.Printf("带约束的泛型求和: %v 和 %v\n",
SumNumbers(ints),
SumNumbers(floats))
}
// SumInts 将映射 m 中的值相加。
func SumInts(m map[string]int64) int64 {
var s int64
for _, v := range m {
s += v
}
return s
}
// SumFloats 将映射 m 中的值相加。
func SumFloats(m map[string]float64) float64 {
var s float64
for _, v := range m {
s += v
}
return s
}
// SumIntsOrFloats 对映射 m 的值求和。它同时支持浮点数和整数作为映射值。
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
// SumNumbers 对映射 m 的值求和。它同时支持整数和浮点数作为映射值。
func SumNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
我将此代码复制并粘贴到 Go Playground 中,在以下位置出现错误:
type Number interface {
int64 | float64 <— 这里 prog.go:6:11: 期望是 ';',但找到了 '|' (以及其他 5 个错误)
}
这个错误是因为Go 1.18的泛型语法在显式指定类型参数时使用的是方括号[],而不是尖括号<>。你的代码中使用了尖括号,这会导致语法错误。
正确的泛型函数调用应该是这样的:
package main
import "fmt"
type Number interface {
int64 | float64
}
func main() {
ints := map[string]int64{
"first": 34,
"second": 12,
}
floats := map[string]float64{
"first": 35.98,
"second": 26.99,
}
fmt.Printf("Non-Generic Sums: %v and %v\n",
SumInts(ints),
SumFloats(floats))
// 正确的泛型函数调用语法
fmt.Printf("Generic Sums: %v and %v\n",
SumIntsOrFloats[string, int64](ints),
SumIntsOrFloats[string, float64](floats))
fmt.Printf("Generic Sums, type parameters inferred: %v and %v\n",
SumIntsOrFloats(ints),
SumIntsOrFloats(floats))
fmt.Printf("Generic Sums with Constraint: %v and %v\n",
SumNumbers(ints),
SumNumbers(floats))
}
// SumInts adds together the values of m.
func SumInts(m map[string]int64) int64 {
var s int64
for _, v := range m {
s += v
}
return s
}
// SumFloats adds together the values of m.
func SumFloats(m map[string]float64) float64 {
var s float64
for _, v := range m {
s += v
}
return s
}
// SumIntsOrFloats sums the values of map m.
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
// SumNumbers sums the values of map m.
func SumNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
关键修正点在第25-26行:
- 错误语法:
SumIntsOrFloats<string, int64>(ints) - 正确语法:
SumIntsOrFloats[string, int64](ints)
Go语言的泛型使用方括号[]来指定类型参数,这是与其他语言(如C++、Java、TypeScript)使用尖括号<>的主要区别。

