函数返回的结构在其所属的数组中未更改

时间:2019-03-23 21:24:30

标签: go

我正在Gotk3中编写一个小型GUI应用程序,这是我用伪代码进行的基本设置:

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获取最近的Point效果很好,但我从未获得用于遍历IsSelected属性为true的点的控制台输出,也没有得到蓝色的绘制点(这将表明已选择此点。

这给我留下了一个问题,即返回的结构(实际上是最初分配给该函数的切片的一部分)是按值而不是按引用返回的。因此,对此返回点进行更改不会更改它以前所属的数组中的点吗?

1 个答案:

答案 0 :(得分:2)

如果在切片中推送非指针值,然后一个函数从该切片返回一个值,则它将是该值的副本。因此,如果更改该值的属性,则不会影响切片中的值。

您可以:

  • 设置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
    }
}