【问题标题】:Usage of the `import` statement`import` 语句的使用
【发布时间】:2014-06-26 07:43:25
【问题描述】:

有人可以解释一下import 语句的工作原理吗?

例如我在myapp/app/models 包中有一个类型User

package models

type User struct {
    // exportod fields
}

我在myapp/app/controllers 包中有一个类型Users

package controllers

import (
    _ "myapp/app/models"
    "github.com/revel/revel"
)

type Users struct {
    *revel.Controller
}

func (c Users) HandleSubmit(user *User) revel.Result {
    // Code here
}

这给了我以下错误:

undefined: User

我尝试将导入更改为以下代码:

import (
    . "advorts/app/models"
    "github.com/revel/revel"
)

但是得到这个错误:

undefined: "myapp/app/controllers".User

我也不明白。那么,import . "something"import "something" 有什么区别?在我的情况下如何正确import我的模型?

【问题讨论】:

  • import . "something" 如果您熟悉 Python,则类似于 from something import *。在最基本的意义上,您将“某物”包的内容导入到当前命名空间中,因此它不是something.NewThing(),而是简单的NewThing()。尽管测试框架 Ginkgo 以一种非常有效的方式使用了它,但恕我直言,它通常是被避免的。至于布局的导入问题,我建议重新阅读有关如何布局 Go 项目的文档。

标签: import go


【解决方案1】:

每个包都有一组类型、函数、变量等。我们称它们为实体。每个实体都可以导出(其名称以大写字母开头)或未导出(其名称以小写字母开头)。

一个包只能访问另一个包的导出实体。为此,它需要import 它,这将使导出的实体可用包名作为标识符。示例:

import "github.com/revel/revel"

将获取revel 包的所有导出实体,这些实体将使用revel. 前缀提供。如revel.Controller 中的Controller 类型,在revel 包中定义。

您可以通过在导入路径前加上想要的标识符来给包标识符起别名。示例:

import rev "github.com/revel/revel"

将导入标识符为 rev 的所有 revel 实体。所以revel.Controller 变成了rev.Controller。如果你有多个同名的包,或者一个包的名字长得离谱的包,这很有用。

作为奖励,您可以匿名导入包,方法是将其别名为空白标识符:

import _ "github.com/revel/revel"

这将导入包,但不允许您访问导出的实体。它对于您需要导入但从不访问的驱动程序之类的东西很有用。一个常见的例子是数据库驱动程序,它们将自己注册到 database/sql 包中,因此您无需直接访问它们。

作为额外奖励,您还可以在本地导入一个包,方法是使用 . 标识符对其进行别名。导出的实体将在没有标识符的情况下可用,就像您在同一个包中定义它们一样。

如何正确导入您的包取决于您。一般的约定是,如果您可以管理它,则永远不要使用别名,隐藏您不需要访问但仍需要导入的包(数据库驱动程序),仅此而已。你真的不需要在本地导入一个包,即使一些教程或框架为了简单起见这样做了。

【讨论】:

    猜你喜欢
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 2020-09-12
    • 2019-11-26
    • 2017-08-02
    • 1970-01-01
    相关资源
    最近更新 更多