Golang中类型 *[]int 不支持索引访问怎么办

Golang中类型 *[]int 不支持索引访问怎么办 请看这段简单的代码

package main

import (
	"fmt"
	"reflect"
)

func main()  {
	var s1 []int = []int{1, 2, 3, 4}
	fmt.Println("Value:", s1, "\n",
		 	 "Type:", reflect.TypeOf(s1), "\n")

	var s2 = &s1
	s2[1] = 2333
	fmt.Println("Value:", s2, "\n",
		         "Type:", reflect.TypeOf(s2), "\n")

}

当我运行这段代码时,得到以下错误信息:

invalid operation: s2[1] (type *[]int does not support indexing)

但是下面这段代码运行正常

package main

import (
	"fmt"
)

func main()  {
	a := [...]int{1, 2, 3}
	b := a
	b[1] = 5
	fmt.Println(a)
	fmt.Println(b)

}

它输出:

[1 2 3] [1 5 3]

那么这是为什么呢?


更多关于Golang中类型 *[]int 不支持索引访问怎么办的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

这样做:

	(*s2)[1] = 2333

参见 https://play.golang.org/p/2lCGtCEx32U

更多关于Golang中类型 *[]int 不支持索引访问怎么办的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,*[]int 是指向切片的指针,而不是切片本身。切片已经是一个引用类型(底层包含指向数组的指针),所以通常不需要再使用指针。当你需要索引访问时,应该对指针进行解引用。

以下是修改后的正确代码:

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var s1 []int = []int{1, 2, 3, 4}
	fmt.Println("Value:", s1, "\n",
		"Type:", reflect.TypeOf(s1), "\n")

	var s2 = &s1
	(*s2)[1] = 2333  // 解引用指针后再索引访问
	fmt.Println("Value:", s2, "\n",
		"Type:", reflect.TypeOf(s2), "\n")
}

或者更简洁地使用自动解引用:

func main() {
	s1 := []int{1, 2, 3, 4}
	s2 := &s1
	
	// 方法1:显式解引用
	(*s2)[1] = 2333
	
	// 方法2:通过原始变量访问
	s1[1] = 2333
	
	fmt.Println("s1:", s1)  // [1 2333 3 4]
	fmt.Println("s2:", *s2) // [1 2333 3 4]
}

关于你的第二个例子能正常运行的原因:

a := [...]int{1, 2, 3}  // 这是数组,不是切片
b := a                  // 数组是值类型,这里发生拷贝
b[1] = 5                // 修改的是b的副本,不影响a

数组是值类型,赋值时会复制整个数组。切片是引用类型,底层指向同一个数组。当你使用 &s1 获取切片指针时,实际上得到了指向切片头结构的指针,需要解引用才能访问底层数据。

如果你确实需要修改切片本身(比如改变长度或容量),可以使用指针:

func modifySlice(s *[]int) {
	*s = append(*s, 5, 6, 7)  // 修改切片本身
}

func main() {
	s := []int{1, 2, 3}
	modifySlice(&s)
	fmt.Println(s)  // [1 2 3 5 6 7]
}

但在大多数情况下,直接传递切片即可,因为切片已经包含指向底层数组的指针:

func modifyElements(s []int) {
	s[0] = 100  // 可以直接修改元素
}

func main() {
	s := []int{1, 2, 3}
	modifyElements(s)
	fmt.Println(s)  // [100 2 3]
}
回到顶部