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.