Golang中如何仅通过文件夹导入包

Golang中如何仅通过文件夹导入包 我正在尝试创建一个API。这个API使用一个“store”,其中包含每个数据库表(或任务)的CRUD端点。这意味着在“store”文件夹中可能有大约100个包。

我该如何将其导入到我的主库中? 仅通过指向文件夹吗? 或者有更好的方法来实现这一点?

image

users.go

package users

func Getusers() string {
   return ("Hi from user")
}

main.go

import "store"

fmt.Println(Getposts)
fmt.Println(Getusers)

我收到的错误信息

./main.go:16:14: undefined: Getpost ./main.go:17:14: undefined: Getuser


更多关于Golang中如何仅通过文件夹导入包的实战教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

你必须使用 store.Getusers

更多关于Golang中如何仅通过文件夹导入包的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


也许是“./store”?

我不知道!我总是使用完全限定的导入,但我以为相对导入应该仍然有效。

我只在刚开始使用 Go 1.4 或 1.5 时尝试过一次相对导入……不过在几分钟后就放弃了,因为当我添加外部依赖后,它们导致了错误(或是警告?)……

不过据我所知,相对导入确实应该以点号开头。

他们不是应该使用 users.Getusers 吗?因为 users 是包名,而 store 是它的路径……

而且,对于较新版本的 Go,这难道不应该失败吗?因为导入的路径中没有主机名。

func main() {
    fmt.Println("hello world")
}

你必须使用 store.Getusers

现在出现了另一个错误:

无法在任何位置找到包 “api_server/main/store”: /usr/local/go/src/api_server/main/store (来自 $GOROOT) /Users/sibert/go/src/api_server/main/store (来自 $GOPATH)

确切的路径是:/usr/local/go/src/api_server/main/store

我哪里做错了?

请问你具体在哪里尝试使用了 storeusers

根据你最初帖子中的代码和文件夹结构,我认为你需要 import "./store",然后使用 users.Getusers()

不过,我不太清楚你的 cat 和 posts.go 文件的情况。如果它们的顶部没有 package users,编译应该会失败,因为每个文件夹只允许有一个包。

包名和它们的导入路径不一定需要匹配。

NobbZ:

难道他们不应该使用 users.Getusers 吗?因为 users 是包名,而 store 是它的路径…

文件夹名称是 “store”,我尝试过将包名设为 “store” 和 “users”。并且我也尝试过导入 “store”、“main/store” 和 “api_server/main/store”。无论如何都会出错。

而且,对于较新版本的 Go 来说,这难道不应该失败吗?因为导入路径中没有主机名。

我使用的 Go 版本是 go1.14.3 darwin/amd64。更新版本会有帮助吗?

在Go语言中,不能直接通过导入文件夹来访问该文件夹下所有包的函数。每个Go包都需要单独导入,并且只能访问该包导出的标识符。

根据你的描述,你有以下几种解决方案:

方案1:为每个子包单独导入(推荐)

// main.go
package main

import (
    "fmt"
    "store/users"
    "store/posts"
)

func main() {
    fmt.Println(users.Getusers())
    fmt.Println(posts.Getposts())
}

方案2:创建聚合包

store目录下创建一个store.go文件,重新导出所有子包的功能:

// store/store.go
package store

import (
    "store/users"
    "store/posts"
)

var (
    Getusers = users.Getusers
    Getposts = posts.Getposts
)

然后主程序可以这样导入:

// main.go
package main

import (
    "fmt"
    "store"
)

func main() {
    fmt.Println(store.Getusers())
    fmt.Println(store.Getposts())
}

方案3:使用接口和工厂模式

如果包之间有共同的行为,可以使用接口:

// store/store.go
package store

type Store interface {
    Get() string
}

func NewUsersStore() Store {
    return &usersStore{}
}

func NewPostsStore() Store {
    return &postsStore{}
}

// store/users/users.go
package users

type usersStore struct{}

func (u *usersStore) Get() string {
    return "Hi from user"
}

// store/posts/posts.go  
package posts

type postsStore struct{}

func (p *postsStore) Get() string {
    return "Hi from post"
}

使用方式:

// main.go
package main

import (
    "fmt"
    "store"
)

func main() {
    userStore := store.NewUsersStore()
    postStore := store.NewPostsStore()
    
    fmt.Println(userStore.Get())
    fmt.Println(postStore.Get())
}

方案4:使用go:embed(Go 1.16+)

如果你需要动态加载包,可以考虑使用embed功能,但这通常用于静态资源而不是代码。

对于你的情况,方案1(单独导入每个子包)是最直接和符合Go惯用法的做法。虽然当有100个包时导入列表会很长,但这样代码最清晰,IDE的自动补全和代码导航也能正常工作。

如果你确实需要减少导入语句,方案2(聚合包)是一个不错的选择,但需要维护聚合文件来同步所有子包的导出。

回到顶部