什么是“。” (点或句点)在Go import语句中做什么?


135

在Go教程中,以及我看过的大多数Go代码中,都是这样导入软件包的:

import (
    "fmt"
    "os"
    "launchpad.net/lpad"
    ...
)

但是在http://bazaar.launchpad.net/~niemeyer/lpad/trunk/view/head:/session_test.go中,gocheck包中的导入(带有.):

import (
    "http"
    . "launchpad.net/gocheck"
    "launchpad.net/lpad"
    "os"    
)

.(期间)的意义是什么?


22
请注意,我在问题中添加了点和句点以使其更易于搜索。
Jared Farrish

Answers:


182

它允许在没有限定符的情况下在本地文件块中引用导入包中的标识符。

如果出现一个明确的句点(。)而不是名称,则所有软件包导出的标识符都将在当前文件的文件块中声明,并且可以在不使用限定符的情况下进行访问。

假设我们已经编译了一个包含package子句package math的软件包,该软件包导出函数Sin,并将编译后的软件包安装在“ lib / math”标识的文件中。下表说明了在各种类型的导入声明之后导入包的文件中如何访问Sin。

Import declaration          Local name of Sin

import   "lib/math"         math.Sin
import M "lib/math"         M.Sin
import . "lib/math"         Sin

参考:http : //golang.org/doc/go_spec.html#Import_declarations


29
应当指出,Go团队不建议使用点导入。在某些情况下,它可能导致某些奇怪的行为,并且可能不是无限期地出现在该语言中。
2011年

在某些情况下,它可能会造成混淆,但是我无法忍受使用go-linq。github.com/ahmetalpbalkan/go-linq
steviesama

请注意,您仍然无法访问未导出的功能(非大写功能)。因此,这种导入方式确实很糟糕。
大卫·天宇·黄

1
使用点导入而不是点导入编译程序时。如果编译后的文件大小存在巨大差异,是否有原因?使用点导入将编译为更大的尺寸。
majidarif

@majidarif:这是一个有趣的观察:)请问您可以用一个复制该问题的代码来发布一个单独的问题吗?(我尝试自己做,使用import "fmt"vs 编译了一个简单的hello-world程序import . "fmt",但在两种情况下,它对我来说都是相同的大小。)
Attilio,

66

这是来自Python的类比:

  • Go的import "os"大致相当于Python的import os
  • Go的import . "os"大致相当于Python的from os import *

在两种语言中,通常都不会使用后者,但是这样做有充分的理由。


4

仅应在测试中使用。

这是golang Wiki中的一些文档

如果您生成了一些模拟代码(例如用模拟生成),并且它导入了您的程序包代码,那么您的测试程序包也会导入了您的程序包代码,则您将得到一个循环依赖项(golang的选择是让用户决定如何解析)。

但是,如果在测试包中对要测试的包使用点符号,则它们将被视为同一包,并且没有循环依赖!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.