2 回答

TA貢獻1852條經驗 獲得超1個贊
如果您有一些代碼在本地機器和 AppEngine 環(huán)境中都可以工作,那么您無需做任何事情。
如果您需要在 AppEngine 上做一些應該或必須做不同的事情,那么您需要檢測環(huán)境并為不同的環(huán)境編寫不同的代碼。
這種檢測和代碼選擇最容易使用構建約束來完成。您可以在.go文件的開頭放置一個特殊的注釋行,它可能會或可能不會編譯和運行,具體取決于環(huán)境。
引用Go 博客:App Engine SDK 和工作區(qū)(GOPATH):
App Engine SDK 引入了一個新的構建約束術語:"appengine". 指定的文件
// +build appengine
將由 App Engine SDK 構建并被 go 工具忽略。相反,指定文件
// +build !appengine
App Engine SDK 會忽略它們,而 go 工具會很高興地構建它們。
例如,您可以有 2 個單獨.go的文件,一個用于 AppEngine,一個用于本地(非 AppEngine)環(huán)境。在兩者中定義相同的函數(shù)(具有相同的參數(shù)列表),因此無論在哪個環(huán)境中構建代碼,該函數(shù)都會有一個聲明。我們將使用這個簽名:
func GetURL(url string, r *http.Request) ([]byte, error)
請注意,*http.Request僅 AppEngine 需要第二個參數(shù) ( )(以便能夠創(chuàng)建 a Context),因此在本地環(huán)境的實現(xiàn)中不使用它(甚至可以是nil)。
一個優(yōu)雅的解決方案可以利用http.Client在標準環(huán)境和 AppEngine 中都可用的類型,并且可以用于執(zhí)行 HTTP GET 請求。一個http.Client值可以在不同的AppEngine被收購,但一旦我們有一個http.Client值,我們可以繼續(xù)以同樣的方式。所以我們將有一個通用代碼來接收一個http.Client并可以完成其余的工作。
示例實現(xiàn)如下所示:
url_local.go:
// +build !appengine
package mypackage
import (
"net/http"
)
func GetURL(url string, r *http.Request) ([]byte, error) {
// Local GetURL implementation
return GetClient(url, &http.Client{})
}
url_gae.go:
// +build appengine
package mypackage
import (
"google.golang.org/appengine"
"google.golang.org/appengine/urlfetch"
"net/http"
)
func GetURL(url string, r *http.Request) ([]byte, error) {
// Appengine GetURL implementation
ctx := appengine.NewContext(r)
c := urlfetch.Client(ctx)
return GetClient(url, c)
}
url_common.go:
// No build constraint: this is common code
package mypackage
import (
"net/http"
)
func GetClient(url string, c *http.Client) ([]byte, error) {
// Implementation for both local and AppEngine
resp, err := c.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}

TA貢獻1863條經驗 獲得超2個贊
- 2 回答
- 0 關注
- 258 瀏覽
添加回答
舉報