不能使用Golang中属于包的导出方法

问题描述 投票:0回答:1

我有一个名为

services
的包。这是包的结构:

services/
    third_party/
       discogs.go
       discogsAPIStructs.go
    artist_srv.go
    auth_srv.go
    record_srv.go

我的艺术家的服务如下:

package services

import (
    "championshipVinyl/entities"
    "championshipVinyl/forms"
    "championshipVinyl/utils"
    "encoding/json"
    "errors"
    "fmt"
    "go.uber.org/zap"
    "gorm.io/gorm"
)

// ArtistService a service representation.
type ArtistService struct {
    Artists []entities.Artist
    db      *gorm.DB
}

// NewArtistService creates a new instance of a category service.
func NewArtistService(db *gorm.DB) *ArtistService {
    return &ArtistService{
        Artists: nil,
        db:      db,
    }
}

func (as ArtistService) FindByName(name string) (entities.BaseEntity, error) { ... }

现在,

services/third_party/discogs.go
如下:

package services

import (
    "championshipVinyl/entities"
    "encoding/json"
    "fmt"
    "gorm.io/gorm"
    "io"
    "io/ioutil"
    "log"
    "net/http"
    "os"
)

type DiscogsAPI struct {
    db *gorm.DB
}

func NewDiscogsAPI(db *gorm.DB) *DiscogsAPI {
    return &DiscogsAPI{
        db: db,
    }
}

我正在尝试向以前的文件添加一个方法,但是在实例化艺术家服务时(

NewArtistService
)我收到错误:

func (da DiscogsAPI) fetchArtist(name string) (entities.BaseEntity, error) {
    s := NewArtistService(da.db)
    fmt.Println(s)
    artist := entities.Artist{}
    return artist, nil 
}

错误提示:

未解析的引用“NewArtistService”

为什么我会收到此错误?我的意思是,

NewArtistService
属于执行调用的同一个包。

如果我改变

s := NewArtistService(da.db)

s := services.NewArtistService(da.db)

错误消失了,但是在编译时出现了预期的导入循环错误,我的意思是,我正在尝试将

services
导入到包内的文件中。

go go-gorm go-gin
1个回答
0
投票

所有包裹都是独特且独立的。您可以按照自己的意愿自由地将它们组织在光盘上,例如阐明关系以便于维护。但是,就编译器而言,光盘上软件包的组织方式与软件包之间的任何关系无关(具有特定记录用途的文件夹名称除外,例如

internal
testdata
)。

简单来说,就您的情况而言,您有 2(两)个包裹:

  • services
  • third_party

事实上,

third_party
包作为包含
services
包的文件夹中的文件夹进行维护,但
third_party
包代码无法访问由
services
包导出的符号;
third_party
代码必须显式导入
services
包并像往常一样限定所需的导出符号:

func (da DiscogsAPI) fetchArtist(name string) (entities.BaseEntity, error) {
    s := services.NewArtistService(da.db)
    // ...

仅根据光盘上包的组织方式,所创建的导入周期“不一定”是可预测的;它依赖于包之间的import关系,无论文件系统组织如何。

即,如果 

services

包包含导入“third_party,”的代码,则

third_party
代码无法在不创建该(非法)导入周期的情况下导入
services
如果没有对您的项目有更广泛的理解和欣赏,很难说,但根据我的经验,当子文件夹中的包依赖于它组织的包时,

within

(如果您愿意,可以是“父”包,尽管如此)请记住,不存在这样的父子关系超出文件系统),这通常是代码异味,表明包组织需要审查和修改。 两个包之间存在导入周期的事实有效地确认了您要么没有您认为拥有的单独包(所有内容都属于

services

包中),要么您没有充分解耦

services 之间的关系
third_party
依赖项。
这个问题没有单一的解决方案。  只有您或对更广泛的项目有类似全面了解的人才能通过重构代码来解决当前存在的循环依赖关系来解决此问题。

© www.soinside.com 2019 - 2024. All rights reserved.