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 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程
  • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
  • ¥15 关于smbclient 库的使用
  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?