Home > Software engineering >  How to make a function with inferred nillable comparable generics?
How to make a function with inferred nillable comparable generics?

Time:10-08

Consider the following function:

func NilCompare[T comparable](a *T, b *T) bool {
    if a == nil && b == nil {
        // if both nil, we consider them equal
        return true
    }
    if a == nil || b == nil {
        // if either is nil, then they are clearly not equal
        return false
    }
    return *a == *b
}

This function works. However, when I call it, I must supply the type, as Go cannot infer (cannot infer T) it, e.g. NilCompare[string](a, b), where a and b are *string.

If I modify T to be *comparable and a and b to be T, I get this error instead: cannot use type comparable outside a type constraint: interface is (or embeds) comparable

I am using Go 1.19.2.

$ go version
go version go1.19.2 linux/amd64

Ironically, my IDE (GoLand 2022.2.3) believes that the above function should be inferrable.

Is there a way to make a function that take nillable comparable and make it inferrable? Or am I doing it correct, but I need to help the go function along?

CodePudding user response:

Type inference just works, in this case. You simply can't infer T using literal nil, as NilCompare(nil, nil) because that doesn't really carry type information.

To test your function with nils do this:

package main

import "fmt"

func main() {
    var a *string = nil
    var b *string = nil
    // a and b are explicitly typed
    res := NilCompare(a, b) // T inferred
    fmt.Println(res) // true
}

this also would work:

func main() {
    // literal nil converted to *string
    res := NilCompare((*string)(nil), (*string)(nil)) // T inferred
    fmt.Println(res) // true
}
  • Related