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