Home > Backend Development > Golang > Can Go Generics' `comparable` Constraint Be Relaxed for Map Keys?

Can Go Generics' `comparable` Constraint Be Relaxed for Map Keys?

Susan Sarandon
Release: 2024-12-18 12:38:22
Original
667 people have browsed it

Can Go Generics' `comparable` Constraint Be Relaxed for Map Keys?

Go generics: type constraint for map keys?

In Go 1.18 and earlier, the predeclared comparable constraint is required for types that are used as map keys. This constraint ensures that the type supports the == and != operators and does not panic when these operators are used.

However, this constraint is not always appropriate for types that can be used as map keys. For example, the following code defines a generic linked list:

type List[X any] interface {
    isList()
}

type Cons[X any] struct {
    Data X
    Next List[X]
}

func (Cons[X]) isList() {}

type Nil[X any] struct{}

func (Nil[X]) isList() {}
Copy after login

This code defines a List interface that is implemented by two types: Cons and Nil. The Cons type represents a non-empty list, while the Nil type represents an empty list.

The following code uses the List interface to create a map of lists to strings:

type List[X any] interface {
    isList()
}

func main() {
    x := Cons[int]{5, Nil[int]{}}
    m := map[List[int]]string{}
    m[x] = "Hi"        // succeeds
    fmt.Println(m[x])  // prints "Hi"
}
Copy after login

This code will compile and run successfully. However, if we try to use a method on the type Cons, we will get a compiler error:

type List[X any] interface {
    isList()
}

func main() {
    x := Cons[int]{5, Nil[int]{}}
    fmt.Println(id(x)) // error: Cons[int] does not implement comparable
}
Copy after login

The error message indicates that the type Cons[int] does not implement the comparable constraint. This is because the Cons type has a field of type List[int], and the List[int] interface does not implement the comparable constraint.

One possible solution to this problem is to use a weaker type constraint. For example, we could use the following constraint:

type List[X any] interface {
    isList()
    Comparable() bool
}
Copy after login

This constraint would allow us to use the Cons type as a map key, even though it does not implement the comparable constraint.

Go 1.20 (February 2023)

The comparable constraint is the correct catch-all constraint for map keys. All types that are comparable as per the Go spec, even if the comparison may panic at run time, can satisfy the comparable constraint. Your code will compile as expected in 1.20.

This finally fixes the inconsistency in previous Go version about spec-comparable types vs comparable types.

The above is the detailed content of Can Go Generics' `comparable` Constraint Be Relaxed for Map Keys?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template