Ensuring strict comparability at compile time in Go 1.20?

王林
Release: 2024-02-11 23:20:08
forward
1041 people have browsed it

确保 Go 1.20 中编译时的严格可比性?

php editor Baicao introduces to you an important feature in Go language version 1.20 - strict comparability at compile time. In Go language version 1.20, new compiler flags are introduced to ensure that the binary files generated during compilation are comparable under different compilation environments. This means that binaries generated under different compilation environments will have the same behavior and results, reducing potential problems caused by different compilation environments. The introduction of this feature will further improve the reliability and stability of the Go language and provide developers with a better development experience.

Question content

In Go 1.18 and Go 1.19, I can ensure at compile time that the type is strictly comparable , i.e. it supports == and != operators, and ensure that these operators do not panic when they run.

This is useful, for example, to avoid inadvertently adding fields to a structure, causing unnecessary panic.

I just tried to instantiate it with comparable :

// supports == and != but comparison could panic at run time
type Foo struct {
    SomeField any
}

func ensureComparable[T comparable]() {
    // no-op
}

var _ = ensureComparable[Foo] // doesn't compile because Foo comparison may panic
Copy after login

This is possible in Go 1.18 and 1.19 due to the definition of comparable constraints:

The predeclared interface type comparable denotes the set of all non-interface types that are comparable
Copy after login

Although the Go 1.18 and 1.19 specifications do not mention types that are not interfaces but cannot be strictly compared, such as [2]fmt.Stringer or struct { foo any }, gc compile The compiler does reject these as arguments to comparable.

A playground with several examples: https://go.dev/play/p/_Ggfdnn6OzZ

In Go 1.20, instantiation of comparable will be consistent with the broader concept of comparability. This makes ensureComparable[Foo] compile even though I don't want it .

Is there a way to statically ensure strict comparability with Go 1.20?

Workaround

To test whether Foo is strictly comparable in Go 1.20, use a type parameter## constrained by Foo #instantiationensureComparable.

// unchanged
type Foo struct {
    SomeField any
}

// unchanged
func ensureComparable[T comparable]() {}

// T constrained by Foo, instantiate ensureComparable with T
func ensureStrictlyComparable[T Foo]() {
    _ = ensureComparable[T] // <---- doesn't compile
}
Copy after login

This solution was originally suggested by Robert Griesemer here . a>

So how does it work?

Go 1.20 introduced

implementing the interface and satisfying constraints:

The second point is to allow interfaces and types with interfaces to instantiate

comparable exceptions.

Now in Go 1.20, type

Foo itself can be instantiated comparable due to satisfiability exceptions. But the type parameter T is not Foo. Compatibility definitions for type parameters are different : The type set of

T contains a type Foo that is not strictly comparable (because it has an interface field), so T is not comparable . Even Foo itself.

This trick effectively makes the program fail to compile if

Foo's operators == and != are likely to panic at runtime.

The above is the detailed content of Ensuring strict comparability at compile time in Go 1.20?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!