使用指向数组的指针

Sea*_*ean 32 pointers go

我正在玩谷歌的Go语言,我遇到了一些在C语言中相当基本的东西,但是到目前为止我看到的文档似乎没有涉及

当我将一个指向一个切片的指针传递给一个函数时,我假设我们有一些方法可以访问它,如下所示:

func conv(x []int, xlen int, h []int, hlen int, y *[]int)

    for i := 0; i<xlen; i++ {
        for j := 0; j<hlen; j++ {
            *y[i+j] += x[i]*h[j]
        }
    }
 }
Run Code Online (Sandbox Code Playgroud)

但Go编译器不喜欢这样:

sean@spray:~/dev$ 8g broke.go
broke.go:8: invalid operation: y[i + j] (index of type *[]int)
Run Code Online (Sandbox Code Playgroud)

足够公平 - 这只是猜测.我有一个相当简单的解决方法:

func conv(x []int, xlen int, h []int, hlen int, y_ *[]int) {
    y := *y_

    for i := 0; i<xlen; i++ {
        for j := 0; j<hlen; j++ {
            y[i+j] += x[i]*h[j]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但肯定有更好的方法.令人讨厌的是,在Google上搜索信息并不是很有用,因为大多数搜索字词都会出现各种C/C++ /无关结果.

Joh*_*n K 25

Google Go文档说明了传递数组的以下内容 - 他们说你通常想传递切片(而不是指针?):

更新:

如@Chincha的评论所示,数组切片是参考,这就是为什么它们有效传递的原因.因此,您可能希望使用切片机制而不是"原始"指针.

来自Google Effective Go doc http://golang.org/doc/effective_go.html#slices

切片是参考类型,


原版的

它在标题之下

关于类型的插曲

[... snip ...]当将数组传递给函数时,您几乎总是希望将形式参数声明为切片.当你调用函数时,获取数组的地址,Go将创建(有效)切片引用并传递它.

编者注:现在不再是这样了

使用切片可以编写此函数(来自sum.go):

09    func sum(a []int) int {   // returns an int
10        s := 0
11        for i := 0; i < len(a); i++ {
12            s += a[i]
13        }
14        return s
15    }
Run Code Online (Sandbox Code Playgroud)

并像这样调用它:

19        s := sum(&[3]int{1,2,3})  // a slice of the array is passed to sum    
Run Code Online (Sandbox Code Playgroud)

也许将整个数组作为切片传递.谷歌通过切片有效地表明Go交易.这是问题的替代答案,但也许这是一种更好的方法.


Ark*_*kku 17

具有空的类型[],例如[]int实际上是切片,而不是数组.在Go中,数组的大小是类型的一部分,所以要实际拥有一个数组,你需要有类似的东西[16]int,并指向那个*[16]int.所以,你实际上已经在做的是使用切片,并且指向切片的指针*[]int是不必要的,因为切片已经通过引用传递.

还要记住,您可以轻松地传递一个切片,指向整个数组&array(只要切片的元素类型与数组的元素类型匹配). (不再.)

例:

package main
import "fmt"

func sumPointerToArray(a *[8]int) (sum int) {
    for _, value := range *a { sum += value }
    return
}
func sumSlice (a []int) (sum int) {
    for _, value := range a { sum += value }
    return
}
func main() {
    array := [...]int{ 1, 2, 3, 4, 5, 6, 7, 8 }
    slice := []int{ 1, 2, 3, 4 }
    fmt.Printf("sum arrray via pointer: %d\n", sumPointerToArray(&array))
    fmt.Printf("sum slice: %d\n", sumSlice(slice))
    slice = array[0:]
    fmt.Printf("sum array as slice: %d\n", sumSlice(slice))
}
Run Code Online (Sandbox Code Playgroud)

编辑:更新以反映自首次发布以来Go中的更改.


Beh*_*ooz 5

添加和删​​除分号和星号.

*y [i + j] + = x [i]*h [j]
- >
(*y)[i + j] + = x [i]*h [j];