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 is called prior to main.
func init() {
d = new(PostgresDriver)
sql.Register("postgres", d)
}
如何使用init
我们使用下划线标识符作为别名导入包,完成了这个调用。这种方法可以让编译器在导入未被引用的包时不报错,而且依旧会定位到包内的init函数。代码如下:
import (
_ "December15/sample/matchers"
"December15/sample/search"
)
或者这样使用数据库
package main
import (
"database/sql"
_ "github.com/goinaction/code/chapter3/dbdriver/postgres"
)
// main is the entry point for the application.
func main() {
sql.Open("postgres", "mydb")
}
结构类型
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
}
搜索匹配可以这样用正则搞
for _, channelItem := range document.Channel.Item {
// Check the title for the search term.
matched, err := regexp.MatchString(searchTerm, channelItem.Title)
if err != nil {
return nil, err
}
// If we found a match save the result.
if matched {
results = append(results, &search.Result{
Field: "Title",
Content: channelItem.Title,
})
}
至此完成了本书前两章的对golang语法和语言结构的概览,下一章将开始对打包和工具链的介绍。
参考:Kennedy W , Ketelsen B , Martin E S . Go in action. 2016.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。