Golang中如何反转指针数组的切片?

Golang中如何反转指针数组的切片? 大家好,

我有这段代码片段 (请忽略反射部分,仅用于调试目的)

func (p Path) GenerateNeighbour() *Path {
	randGen := rand.New(rand.NewSource(time.Now().UnixNano()))

	nodes := make(NodeArray, p.Nodes.Len())
	copy(nodes, p.Nodes)

	fmt.Printf("NODES:%s\n\n", nodes)

	randI := randGen.Intn(nodes.Len())
	randJ := randGen.Intn(nodes.Len())

	nodes.Swap(randI, randJ)
	if randI > randJ {
		r := sort.Reverse(nodes[randJ:randI])
		fmt.Println(r)
		fmt.Println(reflect.TypeOf(r))
		copy(nodes[randJ:], r.(NodeArray)[:])
	} else {
		r := sort.Reverse(nodes[randI:randJ])
		fmt.Println(r)
		fmt.Println(reflect.TypeOf(r))

		copy(nodes[randI:], r.(NodeArray)[:])
	}

	fmt.Println(nodes)
	return &Path{nodes}
}

其中Path是一个包含NodeArray的结构体

type Path struct {
	Nodes NodeArray
}

NodeArray实际上就是实现了sort.Interface接口的[]*Node

type NodeArray []*Node

目前运行时,Go会在copy(nodes[randI:], r.(NodeArray)[:])处出现panic(无论哪个分支),并告诉我r的类型是*sort.reverse

我想要做的是从数组中取一个切片,反转它,然后以新的顺序放回去。sort.Interface似乎让我能够简单地实现这一点,同时提供了sort.Swap方法,这在前一步交换节点时对我很有帮助

由于类型问题,我不知道在反转后如何将数组放回原位……

谢谢!


更多关于Golang中如何反转指针数组的切片?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

现在我明白了,在你评论之前我写了这个,但保留了问题,因为我想理解其中的机制。谢谢你!

func (n NodeArray) Reverse() NodeArray {
	l := len(n)
	rev := make(NodeArray, l)
	copy(rev, n)
	for i, j := 0, l-1; i < j; i, j = i+1, j-1 {
		rev[i] = n[j]
		rev[j] = n[i]
	}
	return rev
}

更多关于Golang中如何反转指针数组的切片?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,sort.Reverse返回的是包装了原始切片的sort.Interface接口,而不是可以直接使用的切片。要反转切片,应该使用sort.Sort对反转后的接口进行排序。

以下是修正后的代码:

func (p Path) GenerateNeighbour() *Path {
    randGen := rand.New(rand.NewSource(time.Now().UnixNano()))
    
    nodes := make(NodeArray, p.Nodes.Len())
    copy(nodes, p.Nodes)
    
    randI := randGen.Intn(nodes.Len())
    randJ := randGen.Intn(nodes.Len())
    
    // 确保 randI < randJ
    if randI > randJ {
        randI, randJ = randJ, randI
    }
    
    nodes.Swap(randI, randJ)
    
    // 反转切片部分
    sliceToReverse := nodes[randI:randJ]
    sort.Sort(sort.Reverse(sort.Interface(sliceToReverse)))
    
    return &Path{nodes}
}

关键修改:

  1. 统一处理索引,确保randI < randJ
  2. 直接使用sort.Sort(sort.Reverse(slice))来反转切片
  3. 移除了不必要的类型断言和copy操作

sort.Reverse返回的接口可以直接传递给sort.Sort进行排序,排序后的结果会直接反映在原始切片中,无需额外的复制操作。

这样修改后,代码会更加简洁且不会出现类型相关的panic。

回到顶部