Was macht das '.' (Punkt oder Punkt) in einer Go-Importanweisung tun?

135

Im Go-Tutorial und im größten Teil des Go-Codes, den ich mir angesehen habe, werden Pakete wie folgt importiert:

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

In http://bazaar.launchpad.net/~niemeyer/lpad/trunk/view/head:/session_test.go wird das Gocheck-Paket jedoch mit einem .(Punkt) importiert :

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

Welche Bedeutung hat die .(Periode)?

Eric Seidel
quelle
22
Beachten Sie, dass ich der Frage Punkt und Punkt hinzugefügt habe, um die Suche zu vereinfachen.
Jared Farrish

Antworten:

182

Damit können die Bezeichner im importierten Paket ohne Qualifizierer im lokalen Dateiblock referenziert werden.

Wenn anstelle eines Namens ein expliziter Punkt (.) Angezeigt wird, werden alle exportierten Bezeichner des Pakets im Dateiblock der aktuellen Datei deklariert und können ohne Qualifizierer aufgerufen werden.

Angenommen, wir haben ein Paket kompiliert, das das Paketklauselpaket math enthält, das die Funktion Sin exportiert, und das kompilierte Paket in der durch "lib / math" gekennzeichneten Datei installiert. Diese Tabelle zeigt, wie auf Sin in Dateien zugegriffen werden kann, die das Paket nach den verschiedenen Arten der Importdeklaration importieren.

Import declaration          Local name of Sin

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

Ref: http://golang.org/doc/go_spec.html#Import_declarations

Tvanfosson
quelle
29
Es ist zu beachten, dass das Go-Team die Verwendung des Punktimports nicht empfiehlt. Es kann in bestimmten Fällen zu merkwürdigem Verhalten führen und ist möglicherweise nicht auf unbestimmte Zeit in der Sprache.
Jimt
In einigen Szenarien mag es verwirrend sein, aber ich konnte es nicht ertragen, go-linq zu verwenden. github.com/ahmetalpbalkan/go-linq
steviesama
Beachten Sie, dass Sie immer noch keinen Zugriff auf nicht exportierte Funktionen (Funktionen in Großbuchstaben) erhalten. Diese Art des Importierens ist also wirklich zum Kotzen.
David 天宇 Wong
1
Beim Kompilieren eines Programms mit Punktimport statt ohne Punktimport. Gibt es einen Grund, warum es einen großen Unterschied bei der kompilierten Dateigröße gibt? Durch die Verwendung des Punktimports wird eine größere Größe erreicht.
Majidarif
@majidarif: Das ist eine interessante Beobachtung :) Könnten Sie bitte eine separate Frage dazu mit Code posten, der das Problem reproduziert? (Ich habe versucht, es selbst zu tun und ein einfaches Hallo-Welt-Programm mit import "fmt"vs zu kompilieren import . "fmt", aber in beiden Fällen war es für mich gleich groß.)
Attilio
66

Hier ist eine Analogie für diejenigen, die aus Python kommen:

  • Go's import "os"entspricht in etwa Pythonsimport os
  • Go's import . "os"entspricht in etwa Pythonsfrom os import *

In beiden Sprachen ist die Verwendung von Letzterem im Allgemeinen verpönt, aber es kann gute Gründe dafür geben.

Evan Shaw
quelle
4

Dies sollte nur zum Testen verwendet werden.

Hier ist eine Dokumentation in Golangs Wiki

Wenn Sie einig Mock - Code wie mit mockgen generiert haben und es importiert Ihren Paketcode, und dann testet Paket auch importiert Ihren Paketcode, erhalten Sie eine zirkuläre Abhängigkeit (etwas golang wählt den Benutzer zu lassen , wie zu lösen , um zu entscheiden).

Wenn Sie jedoch in Ihrem Testpaket die Punktnotation für das zu testende Paket verwenden, werden diese als dasselbe Paket behandelt und es besteht keine zirkuläre Abhängigkeit!

Eli Davis
quelle