Структура, возвращаемая функцией, не изменяется в массиве, которому она принадлежит - PullRequest
0 голосов
/ 24 марта 2019

Я пишу небольшое GUI-приложение на Gotk3, это моя базовая установка в псевдокоде:

type Point struct {
    X float64
    Y float64
    IsSelected bool
}

func getClosestElement(pT []Point, p Point, maxDist float64) Point {
    /* returns the point from pT with the minimum distance to p */
}

func main() {
    // GTK init ..
    selectedPoints := make([]Point, 0)

    /* GTK-Event onMouseClick */
    {
        /* if left mouse click */
        selectedPoints = append(selectedPoints, Point{X: event.x, Y: event.y})
        /* if right mouse click */
        closestPoint = getClosestElement(selectedPoints, Point{X: event.x, Y: event.y}, 15.0)
        closestPoint.IsSelected = true
    }

    /* GTK-Event Draw */
    {
        /* Loop over all selectedPoints */
        if selectedPoint.IsSelected
        /* Draw point in blue and also print to console, if a selected point was detected */
        else
        /* Draw point in black */
    }
}

Но почему-то, хотя получение ближайшего пункта из selectedPoints работает нормальноЯ никогда не получаю консольный вывод для циклического выполнения по точке, свойство IsSelected которой имеет значение true, и при этом я не получаю синюю нарисованную точку (которая указывает на то, что эта точка выбрана).

Это оставляет меня с вопросомесли возвращаемая структура, которая была частью среза, который был изначально передан функции, фактически возвращается по значению, а не по ссылке.Таким образом, изменение этой возвращенной точки не меняет точку в массиве, которой она ранее принадлежала?

1 Ответ

2 голосов
/ 24 марта 2019

Если вы вставите значение не указателя в срез, а затем функция вернет значение из этого среза, это будет копия этого значения. Поэтому, если вы измените свойство этого значения, оно не повлияет на значение в срезе.

Вы можете либо:

  • Сделайте ваши Point значения указателя, например *Point
  • Имейте функцию с именем selectClosestElement, которая устанавливает IsSelected в true и заменяет значение в срезе.

Пример:

// With pointers
// GTK init ..
    selectedPoints := make([]*Point, 0)

    /* GTK-Event onMouseClick */
    {
        /* if left mouse click */
        selectedPoints = append(selectedPoints, &Point{X: event.x, Y: event.y})
        /* if right mouse click */
        closestPoint = getClosestElement(selectedPoints, &Point{X: event.x, Y: event.y}, 15.0)
        closestPoint.IsSelected = true
    }
// With a selectClosestPoint function replacing the value in the slice
// GTK init ..
    selectedPoints := make([]Point, 0)
    /* GTK-Event onMouseClick */
    {
        /* if left mouse click */
        selectedPoints = append(selectedPoints, Point{X: event.x, Y: event.y})
        /* if right mouse click */
        selectClosestPoint(selectedPoints, Point{X: event.x, Y: event.y}, 15.0)
    }
...

func selectClosestPoint(selectedPoints []Point, point Point, maxDist float64) {
    for i, sPoint := range selectedPoints {
        // ...
        // this is the correct point
        sPoint.IsSelected = true
        // Replace it in the slice
        selectedPoints[i] = sPoint
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...