'go1.18 generics cannot use *bytes.Reader as io.Reader
Attempting to map a slice of []byte to a slice of []*byte.Reader for use in mapping to Decode images results in cannot use jpeg.Decode (value of type func(r io.Reader) (image.Image, error)) as func(item *bytes.Reader) (image.Image, error) with go1.18 using generics
package main
import (
"bytes"
"fmt"
"image"
"image/jpeg"
"log"
)
func main() {
imagesBytes := [][]byte{
[]byte("test1"),
[]byte("test2"),
}
jpeg.Decode(bytes.NewReader(imagesBytes[0])) // works
readers := Map(imagesBytes, bytes.NewReader)
images, err := MapWithErr(readers, jpeg.Decode) // cannot use jpeg.Decode (value of type func(r io.Reader) (image.Image, error)) as func(item *bytes.Reader) (image.Image, error) value in argument to MapWithErr[*bytes.Reader, image.Image]compilerIncompatibleAssign
if err != nil {
log.Fatal(err)
}
fmt.Println(images)
}
func MapWithErr[T1 any, T2 any](items []T1, predicate func(item T1) (T2, error)) ([]T2, error) {
output := make([]T2, len(items))
for idx, item := range items {
o, err := predicate(item)
if err != nil {
output = nil
return output, err
}
output[idx] = o
}
return output, nil
}
func Map[T1 any, T2 any](items []T1, predicate func(item T1) T2) []T2 {
output := make([]T2, len(items))
for idx, item := range items {
output[idx] = predicate(item)
}
return output
}
Why is it that I can directly pass a *bytes.Reader into jpeg.Decode() but when mapping and using generics, it doesn't work?
Solution 1:[1]
Because the type of acceptable parameter (io.Reader) in the jpeg.Decode() function is interface type
And if you output bytes.NewReader function
and you pass a type of *byte.Reader to the jpeg.Decode () function, there will be no problem
But the second parameter in the MapWithErr function is of the function type, not the interface, and now the input of this parameter must be fully compatible with the received function and its parameters.
In other words:
*Bytes.Reader and io.Reader types is not equal only *Bytes.Reader can be converted to io.Reader.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mohammad Abbasi |
