Home > front end >  cannot infer V with generic constraint and different argument and return types
cannot infer V with generic constraint and different argument and return types

Time:01-27

I have an interface in go which wants to support saving and loading results in different databases and I want to support different types.

package cfgStorage

type WritableType interface {
    ~int | ~string | ~float64
}

type ConfigStorage[K, V WritableType] interface {
    get(key K) (V, error)
    set(key K, value V) (bool, error)
}

func GetValue[K, V WritableType, C ConfigStorage[K, V]](storage C, key K) (V, error) {
    res, err := storage.get(key)
    return res, err
}

func SetValue[K, V WritableType, C ConfigStorage[K, V]](storage C, key K, value V) (bool, error) {
    res, err := storage.set(key, value)
    return res, err
}

I implemented fileSystem storage for this interface as below:

type FileSystemStorage[K, V WritableType] struct {
}

func (f FileSystemStorage[K, V]) get(key K) (V, error) {
    /// my code to load data from json file
}

func (f FileSystemStorage[K, V]) set(key K, value V) (bool, error) {
/// my code to save data as json file
}

BTW when I try to get an instance from fileSystem and SetValue it works, but for GetValue I faced a compiler error, my test code is as following:

var fileStorage cfgStorage.FileSystemStorage[string, string]

setResult, _ := cfgStorage.SetValue(fileStorage, "key", "value")
if setResult == false {
    t.Error()
}
var result string

result, _ = cfgStorage.GetValue(fileStorage, "key")

The compile error is in the line where I called GetValue:

cannot infer V

If you have any idea how to solve this issue please let me know!

CodePudding user response:

In the function GetValue, it's not possible to infer the type of V with only the provided arguments storage C and key K.

You are asking to infer V from the concrete type that implements the generic constraint ConfigStorage[K, V]. The current type inference algorithm doesn't support this. Related issues in the Go github repository are 50484 and 40018.

Also relevant proposal section about type inference:

We can use function argument type inference for a function call to deduce type arguments from the types of the non-type arguments. We can use constraint type inference to deduce unknown type arguments from known type arguments.

So you could argue that C is not actually known, you only know that it implements the constraint ConfigStorage[K, V].

You must call GetValue with explicit type parameters:

// first string for K, second string for V
GetValue[string, string](fileStorage, "key")

Fixed playground: https://gotipplay.golang.org/p/KoYZ3JMEz2N

  •  Tags:  
  • Related