Golang中无法从模块调用函数的解决方法

Golang中无法从模块调用函数的解决方法 大家好!

我是Go语言的新手,正在边学边做。目前遇到了困难,希望能得到一些帮助,看看我哪里做错了。

我正在尝试在主文件中用Go函数实现一个简单的数据库调用。目前函数返回未定义,我不确定原因。

这是主文件:

package main

import (
	"fmt"
	"sync"
	"time"
)

var wg sync.WaitGroup

func say(s string) {
	for i := 0; i < 3; i++ {
		fmt.Println(s)
		time.Sleep(time.Millisecond * 100)
	}
	wg.Done()

}
func main() {
	db := &Database{data: map[string]interface{}{
		"key0": "value0",
		"key1": "value1",
		"key2": "value2",
		"key3": "value3",
		"key4": "value4",
		"key5": "value5",
		"key6": "value6",
		"key7": "value7",
		"key8": "value8",
		"key9": "value9",
	}}

	fmt.Println(db)
	go getFromDS(db, "key0")
	wg.Add(1)
	go getFromDS(db, "key1")
	wg.Wait()

	fmt.Println(getFromDS)
	fmt.Println(v, err, elapsed)

	// wg.Add(1)
	// go say("Hey")
	// wg.Add(1)
	// go say("There")
	// wg.Wait()
	// wg.Add(1)
	// go say("Hi")
	// wg.Wait()
}

这是文件树:

.
├── datasource
│   ├── cache.go
│   ├── database.go
│   ├── datasource.go
│   ├── datasource_test.go
│   ├── go.mod
│   ├── go.sum
│   └── greetings.go
├── example_Structure.sql
├── go.mod
├── go.sum
├── greetings
│   ├── go.mod
│   └── greetings.go
├── hello
│   └── go.mod
├── main
├── main.go
├── MakeFile
├── README.md
├── scraps.md
└── util
├── go.mod
└── random.go

具体的模块:

package datasource

import (
	"fmt"
	"time"

	"github.com/patrickmn/go-cache"
)

type DataSource interface {
	Value(key string) (interface{}, error)
}

// DataSourceStr type, implements the DataSource interface
type DataSourceStr struct {
	data map[string]string
}

type cachedClient struct {
	c *cache.Cache
}

var c = cache.New(5*time.Minute, 5*time.Minute)

func (n *DataSourceStr) Value(key string) (interface{}, error) {
	/*
		1. Compute a cache key
		2. Search cache key
		3. If hit return value
		4. If miss, do datasource
		5. Cache and return slow thing.
	*/

	cached, found := c.Get(key)
	if found {
		return cached, nil
	} else if _, ok := n.data[key]; ok {
		//measure how often a key gets called.
		fmt.Println(cached)
		c.Set(key, n.data[key], cache.DefaultExpiration)
		return n.data[key], nil
	} else {
		return nil, fmt.Errorf("key not found %v", ok)
	}
}

func getFromDS(datasource DataSource, key string) (string, error) {

	v, err := datasource.Value(key)

	//create a map that decays based on time.

	if err != nil {
		return "", nil
	}

	return fmt.Sprint(v), nil
}

我不明白我哪里做错了!


更多关于Golang中无法从模块调用函数的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

将需要导出的(公开的)函数首字母大写。在你想要使用这些导出函数的地方导入该库。这里有一个非常简单的示例。

├── database │ ├── functions.go ├── main.go ├── go.mod

main.go

package main

import "example/database"

func main() {
    database.Test()
}

database/functions.go

package database

import "fmt"

func Test() {
	fmt.Println("test")
}

go.mod

module example

go 1.15

更多关于Golang中无法从模块调用函数的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题在于你的模块导入和函数调用方式不正确。getFromDS函数定义在datasource包中,但在主文件中没有正确导入该包。

首先,确保你的datasource模块有正确的模块路径。检查datasource/go.mod文件:

module github.com/yourusername/datasource

go 1.21

然后在主项目的go.mod中,添加对datasource模块的依赖:

module yourproject

go 1.21

require github.com/yourusername/datasource v0.0.0

replace github.com/yourusername/datasource => ./datasource

修改主文件,正确导入datasource包:

package main

import (
	"fmt"
	"sync"
	"time"
	
	"github.com/yourusername/datasource"
)

var wg sync.WaitGroup

type Database struct {
	data map[string]interface{}
}

func (db *Database) Value(key string) (interface{}, error) {
	if val, ok := db.data[key]; ok {
		return val, nil
	}
	return nil, fmt.Errorf("key not found")
}

func say(s string) {
	for i := 0; i < 3; i++ {
		fmt.Println(s)
		time.Sleep(time.Millisecond * 100)
	}
	wg.Done()
}

func main() {
	db := &Database{data: map[string]interface{}{
		"key0": "value0",
		"key1": "value1",
		"key2": "value2",
		"key3": "value3",
		"key4": "value4",
		"key5": "value5",
		"key6": "value6",
		"key7": "value7",
		"key8": "value8",
		"key9": "value9",
	}}

	fmt.Println(db)
	
	wg.Add(1)
	go func() {
		v, err := datasource.GetFromDS(db, "key0")
		fmt.Println("key0:", v, err)
		wg.Done()
	}()
	
	wg.Add(1)
	go func() {
		v, err := datasource.GetFromDS(db, "key1")
		fmt.Println("key1:", v, err)
		wg.Done()
	}()
	
	wg.Wait()
}

还需要修改datasource.go文件,将函数名改为大写以导出:

package datasource

import (
	"fmt"
	"time"

	"github.com/patrickmn/go-cache"
)

type DataSource interface {
	Value(key string) (interface{}, error)
}

// DataSourceStr type, implements the DataSource interface
type DataSourceStr struct {
	data map[string]string
}

type cachedClient struct {
	c *cache.Cache
}

var c = cache.New(5*time.Minute, 5*time.Minute)

func (n *DataSourceStr) Value(key string) (interface{}, error) {
	cached, found := c.Get(key)
	if found {
		return cached, nil
	} else if _, ok := n.data[key]; ok {
		fmt.Println(cached)
		c.Set(key, n.data[key], cache.DefaultExpiration)
		return n.data[key], nil
	} else {
		return nil, fmt.Errorf("key not found %v", ok)
	}
}

// GetFromDS 改为大写以导出函数
func GetFromDS(datasource DataSource, key string) (string, error) {
	v, err := datasource.Value(key)

	if err != nil {
		return "", err
	}

	return fmt.Sprint(v), nil
}

运行命令更新依赖:

go mod tidy

现在GetFromDS函数可以从datasource包中正确调用。函数名改为大写是Go语言导出函数的要求,只有大写的函数、变量和类型才能被其他包访问。

回到顶部