【问题标题】:Can I reference an imported type without using dot notation我可以在不使用点符号的情况下引用导入的类型吗
【发布时间】:2021-07-16 18:16:02
【问题描述】:

考虑以下接口定义:

package repos

import (
  resources "unit/pkg/resources"
)

type IRepo interface {
  fetch(int32) (resources.IResource, error)
  update(resources.IResource) (resources.IResource, error)
  new() resources.IResource
  create(resources.IResource) (resources.IResource, error)
  delete(int32) error
}

有没有办法“使用”导入的包(在 C++ 命名空间的意义上),这样我就不需要在每次引用它的一种类型时使用点符号显式命名它(IResource

(TBH - 这可能只是意味着IResource 属于repos 包而不是resources

【问题讨论】:

  • 只定义一个新的包本地类型会很愚蠢吗?例如 - type RepoResource resources.IResource?
  • 如果你需要这个,你可能有设计缺陷,或者你可能只是不习惯 Go。引用命名空间类型是 Go 正常工作的方式。

标签: go namespaces


【解决方案1】:

您可以在 import declaration 前面加上名称 . 以导入其所有标识符:

package repos

import (
  . "unit/pkg/resources"
)

然而, import . 几乎从来都不是合适的解决方案。如果将来将新标识符添加到 resources 包中,它们可能会与 repos 包中的现有标识符发生冲突并破坏您的构建。

此外,包名称与类型名称冗余这一事实可能表明该包或该包中的类型应该有一个更好的名称(有关更多详细信息,请参阅Package names 博客文章)。

在这种情况下,resourcesrepos 之间的抽象边界可能弊大于利。您在这里处理的是什么种类资源? Resource 类型可以移动到更高级别的包中吗?


最后,我要指出IRepo 界面看起来非常大,而且可能不合适。 Go 接口——与 Java 接口不同——通常属于使用该接口的 API,而不是 提供该接口实现的 API。

有关该原则的更多信息,请参阅:

【讨论】:

  • 请不要宣扬坏习惯。
  • 我相信我既回答了所提出的实际问题,也解释了为什么问题本身可能需要采用不同的方法。我认为省略这两个部分对任何人都没有好处。
【解决方案2】:

您可以使用类型别名。

type IRes = resources.IResource

与类型定义相比,别名只是同一类型的另一个名称,而不是新的不同类型。类型定义将没有 =

【讨论】:

  • @donny-nyc,请注意,类型别名并非真正用于此目的,它们主要用于重构和兼容性。代码应该写得有利于读者,使用类型别名只是为了避免输入包标识符,这会使代码的意图变得不清楚。
  • 这是一个非常糟糕的建议,因为它误用了语言功能。
  • @Volker 即使我在某种程度上同意你的观点。我自己更喜欢明确和更冗长。不过,这种观点也有点意见。 AFAIK 没有其他方法可以实现 OP 的要求,他确实明确要求一种方法来做到这一点。
猜你喜欢
  • 1970-01-01
  • 2019-10-25
  • 2021-12-05
  • 2016-02-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
  • 2011-10-24
相关资源
最近更新 更多