dptx8888 2011-05-19 03:47
浏览 77
已采纳

转到:调用将指针传递给数组的函数

I have spent a bit of time attempting to do this, and I think I need a global array (not slice), and I want to pass it as a pointer, not by value. The function receiving the pointer needs to test for nil, and if nil, read the array from disk, using eg: "baForm, oOserr = ioutil.ReadFile(sFormName)". The calling function may pass either a global array or an array local to the calling function which I presume will be garbage collected.

The reason for doing this is that I want a standard function to read the forms from disk, and often-used forms are stored globally. Despite whether some may think there is a better way, I still want to know how to achieve this ie: a) have global or local array, b) not pass by value, c) The global arrays will be read only once from disk and the local arrays will be read each time the function is called. TIA.

  • 写回答

2条回答 默认 最新

  • douyi2664 2011-05-19 08:03
    关注

    Here's a sample program that maintains a dynamic forms buffer based on use count. If the ReadForm function finds a form, it returns the address of the form and a nil error.

    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)
    }
    

    EDIT: Map operations are not atomic. Revise the sample program to use a mutex for concurrent access to the forms map.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序
  • ¥15 onvif+openssl,vs2022编译openssl64
  • ¥15 iOS 自定义输入法-第三方输入法