2014-06-26 96 views
0

有人可以向我解釋import語句的工作原理嗎?`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我的模型在我的情況?

+0

'進口。如果你熟悉Python,那麼「something」就類似於'from something import *'。從最基本的意義上講,你將「something」包的內容導入到當前命名空間中,而不是'something.NewThing()',它只是'NewThing()'。這通常是可以避免的,儘管測試框架Ginkgo以一種非常有效的方式使用它,恕我直言。至於您的佈局導入問題,我建議重新閱讀關於如何佈局Go項目的文檔。 – sberry

回答

4

每個包都有一組類型,函數,變量等。我們稱它們爲實體。可以導出每個實體(其名稱以大寫字母開頭)或未導出(其名稱以小寫字母開頭)。

軟件包只能訪問另一個軟件包的導出實體。要做到這一點,它需要import它,這將使導出的實體可用包名稱作爲標識符。例如:

import "github.com/revel/revel" 

將得到revel包,將使用revel.前綴是可用的全部出口的entites。如revel.Controller,即revel包中定義的Controller類型。

可以通過在導入路徑前添加所需的標識符來爲包標識符設置別名。例如:

import rev "github.com/revel/revel" 

將導入所有revel entites的與該標識符rev。所以revel.Controller變成rev.Controller。如果您有多個具有相同名稱的包或具有荒謬長名稱的包,這會很有用。

作爲獎勵,你可以匿名導入包,通過它別名空白標識符:

import _ "github.com/revel/revel" 

將導入包,但不給你訪問導出的實體。這對於需要導入但不能訪問的驅動程序非常有用。一個常見的例子是數據庫驅動程序,它們將自己註冊到database/sql軟件包,因此您不需要直接訪問它們。

作爲額外的獎勵,您還可以通過使用.標識符進行別名來導入本地包。然後,導出的實體無需標識符即可使用,就好像您在同一個包中定義它們一樣。

如何正確導入你的軟件包取決於你。一般慣例是永遠別名,如果你可以管理它,隱藏你不需要訪問但仍然需要導入的包(數據庫驅動程序),就這些了。你真的永遠不需要在本地導入一個包,即使有些教程或框架爲了簡單起見也會這樣做。