`import`语句的用法

huangapple go评论86阅读模式
英文:

Usage of the `import` statement

问题

有人可以解释一下import语句是如何工作的吗?

例如,我在myapp/app/models包中有一个类型为User的结构体:

package models

type User struct {
    // 导出的字段
}

我在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 {
    // 代码在这里
}

这给我报了以下错误:

undefined: User

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

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

但是得到了这个错误:

undefined: "myapp/app/controllers".User

我也不理解这个错误。那么,import . "something"import "something"之间有什么区别?在我的情况下,如何正确地导入我的模型?

英文:

Can someone explain me how the import statement works ?

For example I have a type User in the myapp/app/models package:

package models

type User struct {
    // exportod fields
}

I have a type Users in the myapp/app/controllers package:

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
}

This gives me the following error:

> undefined: User

I tried to change the imports to the following code:

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

But get this error:

> undefined: "myapp/app/controllers".User

Which I don't understand either. So, what is the difference between import . "something" and import "something" ? How to properly import my model in my case ?

答案1

得分: 10

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

一个包只能访问另一个包的导出实体。为了做到这一点,它需要使用import语句导入该包,这将使得导出的实体可以通过包名作为标识符来访问。例如:

import "github.com/revel/revel"

将会获取revel包的所有导出实体,可以使用revel.前缀来访问它们,比如revel.Controller,它是在revel包中定义的Controller类型。

你可以通过在导入路径前加上所需的标识符来给包标识符取别名。例如:

import rev "github.com/revel/revel"

将使用标识符rev导入所有revel实体。因此,revel.Controller变成了rev.Controller。这在你有多个同名包或包名过长时非常有用。

作为额外的功能,你可以通过将包别名设置为空白标识符来匿名导入一个包:

import _ "github.com/revel/revel"

这将导入该包,但不会让你访问其导出实体。这对于需要导入但不需要直接访问的驱动程序非常有用,比如数据库驱动程序,它们会自动注册到database/sql包中,因此你不需要直接访问它们。

还有一个额外的额外功能,你还可以使用.标识符将包导入到本地。导出的实体将无需标识符即可访问,就像你在同一个包中定义它们一样。

如何正确导入包取决于你自己。通常的约定是,如果可以的话,尽量不使用别名;隐藏你不需要访问但仍需要导入的包(比如数据库驱动程序);就这些了。你真的不需要在本地导入一个包,即使有些教程或框架为了简单起见这样做。

英文:

Each package has a set of types, functions, variables, etc. Let's call them entities. Each entity can be either exported (its name start with an Uppercase letter), or unexported (its name start with a lowercase letter).

A package can only access the exported entites of another package. To do this, it needs to import it, which will make the exported entites available with the package name as identifier. Example:

import "github.com/revel/revel"

will get all exported entites of the revel package, which will be available using revel. prefix. As in revel.Controller, which is the Controller type defined in the revel package.

You can alias a package identifier by prefixing the import path with the wanted identifier. Example:

import rev "github.com/revel/revel"

will import all revel entites with the identifier rev. So revel.Controller becomes rev.Controller. It is useful if you have multiple package with the same name, or a package with an absurdly long name.

As a bonus, you can import a package anonymously, by aliasing it to the blank identifier:

import _ "github.com/revel/revel"

which will import the package, but not give you access to the exported entities. It is useful for things like drivers, which you need to import but never access. A frequent example is the database drivers, which register themselves to the database/sql package so you never need to access them directly.

And as a bonus' bonus, you can also import locally a package, by aliasing it with the . identifier. The exported entites will then be available without identifier, as if you defined them in the same package.

How to properly import your packages is up to you. The general convention is to never alias if you can manage it, to hide the package that you don't need to access but still need to import (database drivers), and that's all. You really never need to import locally a package, even if some tutorials or frameworks do it for simplicity's sake.

huangapple
  • 本文由 发表于 2014年6月26日 15:43:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/24425002.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定