Go:调用一个将指针传递给数组的函数



我花了一些时间尝试这样做,我认为我需要一个全局数组(不是切片),我想将其作为指针传递,而不是按值传递。接收指针的函数需要测试nil,如果为nil,则从磁盘读取数组,例如:"baForm,oOserr = ioutil。ReadFile(sFormName)"。调用函数可能会传递一个全局数组或一个本地数组到调用函数,我认为这些数组将被垃圾回收。

这样做的原因是我想要一个标准函数来从磁盘读取表单,并且常用的表单是全局存储的。尽管有些人是否认为有更好的方法,但我仍然想知道如何实现这一目标,即:a)具有全局或局部数组,b)不按值传递,c)全局数组将仅从磁盘读取一次,并且每次调用函数时都会读取本地数组。蒂亚。

通过阅读您的描述,我不明白为什么将指针传递给数组比传递切片更好 - 但这取决于您。

你可以像在 C 中一样传递指针 - 在声明中附加一个星号 ( *),并在调用函数时将 & 符号 ( & ) 附加到值。

请记住,在 Go 中,数组大小是其类型的一部分。这意味着您的函数声明将嵌入数组大小,因此您不能使用任何不同大小的数组调用函数。仅此原因通常就足以保证使用切片而不是数组。

下面是一个基于使用计数维护动态表单缓冲区的示例程序。如果 ReadForm 函数找到表单,它将返回表单的地址和 nil 错误。

package main
import (
    "fmt"
    "io/ioutil"
    "math"
    "os"
    "sync"
)
type Form struct {
    Name     string
    useCount int64
    Data     []byte
}
// The capacity of the forms buffer.
const formsCap = 2
// The forms buffer.
var (
    forms     = make(map[string]*Form, formsCap)
    formsLock sync.RWMutex
)
func ReadForm(name string) (form *Form, err os.Error) {
    formsLock.RLock()
    form, ok := forms[name]
    formsLock.RUnlock()
    if !ok {
            form = &Form{name, 0, nil}
    }
    if form.Data == nil {
        data, err := ioutil.ReadFile(name + ".form")
        if err != nil {
            return nil, err
        }
        form = &Form{name, 0, data}
        formsLock.Lock()
        if len(forms) >= formsCap {
            minForm := &Form{useCount: math.MaxInt64}
            for i, f := range forms {
                if f.useCount < minForm.useCount {
                    minForm = f
                }
            }
            minform.Data = nil
        }
        forms[name] = form
        formsLock.Unlock()
    }
    form.useCount++
    return form, nil
}
func main() {
    // form files are named name.form e.g. form1.form
    for _, name := range []string{"form1", "form2", "form3"} {
        f, err := ReadForm(name)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Println(string(f.Data))
        }
    }
    fmt.Println(len(forms), forms)
}

编辑:地图操作不是原子的。修改示例程序以使用互斥锁并发访问forms映射。

最新更新