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

11 回复

没有任何行号吗?

更多关于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)使用尖括号<>的主要区别。

回到顶部