繁体   English   中英

如何在同一个 package 但不同的文件夹中导入/使用其他结构

[英]How to import/use other struct in the same package but different folder

我有这样的文件夹结构:

> validations
    > user
        > user.validation.go
    > address
        > address.validation.go

这两个文件的 package 名称是validations

user.validation.go ,我尝试像这样使用地址验证结构:

type UserValidation struct {
   Address AddressValidation // the error says: undeclared name: AddressValidation
}

我试过像这样在结构之前调用 package 名称:

type UserValidation struct {
   Address validations.AddressValidation // the error says: undeclared name: validations
}

我尝试先导入它:

import "example/go-api/validations"

错误提示: AddressValidation not declared by package validations

每个文件夹中都有三个单独的包:

validations
user
address

validations文件夹仅包含其他包,因此无法有效导入; 它不包含任何导出的代码。

user文件夹包含一个名为 package 的validations ,可以有效地导入它以访问导出的UserValidation类型。

address文件夹包含一个名为 package 的validations ,可以有效地导入它以访问导出的AddressValidation类型。

但是 GoLang 并没有把这些都当成一个单一的validations package。一个'包'是一个命名空间,但是同名的包不是同一个命名空间 它们都保持独立和不同的包(和名称空间)。

如果user文件夹中的validations package 希望导入address文件夹中的validations package,它可以这样做,但必须引用该 package 的完整路径并且必须为导入别名,因为文件夹名称与其包含的 package 的名称不匹配:

import validations "example/go-api/validations/address"

type UserValidation struct {
   Address validations.AddressValidation
}

会工作得很好。

但请注意,由于这涉及别名,因此该别名可以是您喜欢的任何东西 - 它不必与导入的名称 package 匹配。即这同样有效:

import v "example/go-api/validations/address"

type UserValidation struct {
   Address v.AddressValidation
}

如果您项目中的其他一些 package 希望同时引用UserValidationAddressValidation ,则它必须导入包含它们的两个单独的validations包,并为每个包提供唯一的别名:

import (
   addressValidations "example/go-api/validations/address"
   userValidations "example/go-api/validations/user"
)

然后可能会做类似的事情:

var (
   av addressValidations.AddressValidation
   uv userValidations.UserValidation
)

所有这一切的关键是文件夹不是在 package 中组织文件的一种方式 一个文件夹package。

除非您有特殊原因不这样做,否则最好:

  1. 将包含其文件的文件夹命名为 package
  2. 为包使用唯一名称(在同一项目/模块中)

规则#2 偶尔会有有效的例外情况,例如 package 名称在两个不同且互斥的上下文中有意义。 也就是说,没有其他 package 永远不会希望或需要从这些不同的上下文中导入同名的不同包。

我还没有遇到规则#1 的有效例外。 :)

可能的替代方法

如果您真的想将UserValidationAddressValidation在单独的包中,您可以将包命名为useraddress (即应用规则 #1:为各自的文件夹命名每个 package)。

然后,由于 package 名称为其中的符号提供了地址或用户上下文,因此您可以在每种情况下将类型重命名为简单的Validation

您的user.go代码将变为:

package user

import "example/go-api/validations/address"

type Validation struct {
   Address address.Validation
}

和您的address.go代码:

package address

type Validation struct {}

并且导入useraddress验证的 package 中的变量变为:

import (
   "example/go-api/validations/address"
   "example/go-api/validations/user"
)

var (
   av address.Validation
   uv user.Validation
)

警告编码器

这不是处方! 在不了解您的具体用例的情况下,我不知道这是否是给这只猫剥皮的最佳方法; 这只是一种方式的说明。

简而言之:使用您的文件夹/包名称来帮助为包导出的符号添加上下文和含义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM