Понимание предупреждения gometalinter о необращении ненужного преобразования

#go

#Вперед

Вопрос:

warning: unnecessary conversion (unconvert)

Это происходит из следующей строки:

offsetY = 60 image.Image(*img.Bitmap).Bounds().Max.Y

Мне потребовалось некоторое время, чтобы понять, как преобразовать этот указатель интерфейса в интерфейс, но я не думаю, что это правильное решение, поскольку gometalinter выдает предупреждение.

Я хочу получить ширину img . img имеет структуру Image и имеет растровый указатель на реальное image.Image изображение (image stdlib). Если я хочу вызвать Bounds фактический image.Image , мне нужно преобразовать указатель на интерфейс в интерфейс.

Как это должно быть сделано более удобным для go способом?

У меня есть следующий код go:

 import (
    "image"
    "image/color"
    "image/draw"
)
type Image struct {
    Src    string
    Title  string
    Width  int
    Height int
    Index  int
    Bitmap *image.Image
}

type Images []Image

offsetY = 10
func ComposeImage(imgs Images) image.Image {
    masterRGBAImg := image.NewRGBA(image.Rect(0, 0, 300, 300))
    masterBounds := masterRGBAImg.Bounds()

    for _, img := range imgs {
        draw.Draw(masterRGBAImg, masterBounds,
            *img.Bitmap, image.Point{X: -10, Y: -offsetY   10}, draw.Src)


        addLabel(masterRGBAImg, 10, offsetY-30, img.Title)

        // HERE ======
        offsetY  = 60   image.Image(*img.Bitmap).Bounds().Max.Y
        // END ======

    }
    return masterRGBAImg
}

// Draw label on image.
func addLabel(img *image.RGBA, x int, y int, label string) {
    col := color.RGBA{50, 50, 50, 255}
    point := fixed.Point26_6{X: fixed.Int26_6(x * 64), Y: fixed.Int26_6(y * 64)}

    d := amp;font.Drawer{
        Dst:  img,
        Src:  image.NewUniform(col),
        Face: inconsolata.Bold8x16,
        Dot:  point,
    }
    d.DrawString(label)
}
  

Ответ №1:

Во-первых, поле bitmap является *image.Image , поэтому оно того же типа, и вам не нужно его преобразовывать, когда вы могли бы просто разыменовать его.

 (*img.Bitmap).Bounds()
  

Однако image.Image — это интерфейс. Указатель на интерфейс — это почти всегда ошибка программирования.

Измените свое определение структуры на

 type Image struct {
    Src    string
    Title  string
    Width  int
    Height int
    Index  int
    Bitmap image.Image
}
  

и затем вы можете просто вызвать img.Bitmap.Bounds() напрямую

Комментарии:

1. Структура та же, вы имеете в виду ` Bitmap *image. Изображение` -> Bitmap image.Image . Программа работала, мне просто повезло?

2. @coulix, упс, да

3. @coulix, тебе не «повезло», это будет работать таким образом, но для этого нет причин, и это только усложняет жизнь.

4. (*img.Bitmap).Bounds() Теперь я получаю ./image.go: 65: недопустимое косвенное изображение img. Растровое изображение (введите изображение. Изображение). На данный момент мне не нужно разыменовывать img.Bitmap верно?

5. @coulix: да. Если вы избавитесь от ненужного указателя, вам не нужно разыменовывать его.