方法数组

Go array for method

我可以在 Go 方法中使用数组及其指针吗?

我有以下代码:

var array = [3]string{"A", "B", "C"}
type arrayTypePt *[3]string
func (m *arrayTypePt) change() { m[1] = "W" }
func main() {
    (arrayTypePt(&array)).changeArray4()
}

但是这段代码:http://play.golang.org/p/mXDEhmA9wk

给我一个错误:

invalid receiver type *arrayTypePt (arrayTypePt is a pointer type)
invalid operation: m[1] (type *arrayTypePt does not support indexing)
arrayTypePt(&array).changeArray4 undefined (type arrayTypePt has no field or method changeArray4)

当我用 slice 尝试这个时,我得到了同样的错误。 为什么我不能在方法中这样做?

如果您将 array/slice 变量定义为接收者类型,它工作正常:

type arrayType [3]string
var array arrayType = [3]string{"A", "B", "C"}   # note "arrayType" here
func (m *arrayType) change() { m[1] = "W" }
func main() {
    array.change()
}

我不确定为什么类型转换会这样。

方法的receiver类型不能是指向指针的指针,但是你是这么写的:

func (m *arrayTypePt) change() { m[1] = "W" }

arrayTypePt 已经是指针 *[3]string。引用自 language specification:

[The receiver] type must be of the form T or *T (possibly using parentheses) where T is a type name. The type denoted by T is called the receiver base type; it must not be a pointer or interface type and it must be declared in the same package as the method.

你的第二个错误("type *arrayTypePt does not support indexing")也是这个的结果(m是指向指针的指针,这就是你不能索引的原因它;如果它只是指向数组或切片的指针,则指针间接寻址将是自动的)。

你的第三个错误只是一个拼写错误,你声明了一个名为 change() 而不是 changeArray4() 的方法。

所以你应该只命名非指针数组类型:

type arrayType [3]string

你可以直接使用这种类型来声明你的数组:

var array = arrayType{"A", "B", "C"}

你可以简单地调用它的 change() 方法:

array.change()

会自动获取数组的地址(因为change()方法有一个指针接收者但是array变量本身不是指针)

Go Playground 上试试。

注释/备选方案

如果您希望 array 变量显式 [3]string,您仍然可以通过将其转换为 arrayType、将其设置为另一个变量并 change() 可以被调用(因为它是一个变量,它的地址可以被获取——而像 arrayType(arr) 这样的转换的地址不能):

arr2 := [3]string{"A", "B", "C"}
arr3 := arrayType(arr2)
arr3.change()

或者如果您将变量声明为指向类型 [3]string 的指针,您可以保存所需的附加变量(这只是我们能够获取其地址所必需的):

arr4 := new([3]string)
*arr4 = [3]string{"A", "B", "C"}
((*arrayType)(arr4)).change()

也可以在 Go Playground 上尝试这些变体。