init
init 内容
本书举荐将 map 映射(或者叫注册)之类的筹备工作放在 init 外面,Golang 会保障 init 中的函数在 main 函数调用之前执行结束。例如:
// init registers the default matcher with the program.
func init() {
var matcher defaultMatcher
Register("default", matcher)
}
// Register is called to register a matcher for use by the program.
func Register(feedType string, matcher Matcher) {if _, exists := matchers[feedType]; exists {log.Fatalln(feedType, "Matcher already registered")
}
log.Println("Register", feedType, "matcher")
matchers[feedType] = matcher
}
如何应用 init
咱们应用下划线标识符作为别名导入包,实现了这个调用。这种办法能够让编译器在导入未被援用的包时不报错,而且依旧会定位到包内的 init 函数。代码如下:
import (
_ "December15/sample/matchers"
"December15/sample/search"
)
构造类型
golang 中没有类的概念,这里的构造类型的作用就相当于 java 外面的类,例如这里定义了 4 个类:
type (
// item defines the fields associated with the item tag
// in the rss document.
item struct {
XMLName xml.Name `xml:"item"`
PubDate string `xml:"pubDate"`
Title string `xml:"title"`
Description string `xml:"description"`
Link string `xml:"link"`
GUID string `xml:"guid"`
GeoRssPoint string `xml:"georss:point"`
}
// image defines the fields associated with the image tag
// in the rss document.
image struct {
XMLName xml.Name `xml:"image"`
URL string `xml:"url"`
Title string `xml:"title"`
Link string `xml:"link"`
}
// channel defines the fields associated with the channel tag
// in the rss document.
channel struct {
XMLName xml.Name `xml:"channel"`
Title string `xml:"title"`
Description string `xml:"description"`
Link string `xml:"link"`
PubDate string `xml:"pubDate"`
LastBuildDate string `xml:"lastBuildDate"`
TTL string `xml:"ttl"`
Language string `xml:"language"`
ManagingEditor string `xml:"managingEditor"`
WebMaster string `xml:"webMaster"`
Image image `xml:"image"`
Item []item `xml:"item"`}
// rssDocument defines the fields associated with the rss document.
rssDocument struct {
XMLName xml.Name `xml:"rss"`
Channel channel `xml:"channel"`
}
)
空构造实现接口
本书举荐在不须要保护任何状态的时候,用空构造体来实现接口,比方:
cxtype rssMatcher struct{}
func (m rssMatcher) Search(feed *search.Feed, searchTerm string) ([]*search.Result, error) {...}
网络申请
Golang 能够十分分不便的进行网络申请,例如:
// retrieve performs a HTTP Get request for the rss feed and decodes the results.
func (m rssMatcher) retrieve(feed *search.Feed) (*rssDocument, error) {
if feed.URI == "" {return nil, errors.New("No rss feed uri provided")
}
// Retrieve the rss feed document from the web.
resp, err := http.Get(feed.URI)
if err != nil {return nil, err}
// Close the response once we return from the function.
defer resp.Body.Close()
// Check the status code for a 200 so we know we have received a
// proper response.
if resp.StatusCode != 200 {return nil, fmt.Errorf("HTTP Response Error %d\n", resp.StatusCode)
}
// Decode the rss feed document into our struct type.
// We don't need to check for errors, the caller can do this.
var document rssDocument
err = xml.NewDecoder(resp.Body).Decode(&document)
return &document, err
}
参考:Kennedy W , Ketelsen B , Martin E S . Go in action. 2016.