2009-11-21 66 views
10

我想知道這裏發生了什麼。函數實現接口

有一個HTTP處理程序接口:

type Handler interface { 
    ServeHTTP(*Conn, *Request) 
} 

此實現,我想我明白了。

type Counter int 

func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) { 
    fmt.Fprintf(c, "counter = %d\n", ctr); 
    ctr++; 
} 

從我的理解是,該類型的「計數器」實現該接口,因爲它具有所需簽名的方法。到現在爲止還挺好。然後給出這個例子:

func notFound(c *Conn, req *Request) { 
    c.SetHeader("Content-Type", "text/plain;", "charset=utf-8"); 
    c.WriteHeader(StatusNotFound); 
    c.WriteString("404 page not found\n"); 
} 

// Now we define a type to implement ServeHTTP: 
type HandlerFunc func(*Conn, *Request) 
func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) { 
    f(c, req) // the receiver's a func; call it 
} 
// Convert function to attach method, implement the interface: 
var Handle404 = HandlerFunc(notFound); 

有人可以詳細說明爲什麼或這些不同的函數如何配合在一起?

回答

12

此:

type Handler interface { 
    ServeHTTP(*Conn, *Request) 
} 

說,滿足Handler接口必須有一個ServeHTTP方法的任何類型。以上內容將在包裝http內。

type Counter int 

func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) { 
    fmt.Fprintf(c, "counter = %d\n", ctr); 
    ctr++; 
} 

這就在計數器類型上對應於ServeHTTP的方法。這是一個與以下不同的例子。

從我的理解是,該 「計數器」類型實現了 接口,因爲它有 具有所需簽名的方法。

沒錯。

本身下面的功能將無法正常工作,一個Handler

func notFound(c *Conn, req *Request) { 
    c.SetHeader("Content-Type", "text/plain;", "charset=utf-8"); 
    c.WriteHeader(StatusNotFound); 
    c.WriteString("404 page not found\n"); 
} 

這個東西剩下的就是裝修上面,這樣它可以是一個Handler

在下文中,一個HandlerFunc是一個函數,它有兩個參數,指針Conn指針Request,並且沒有返回。換句話說,任何接受這些參數並且什麼都不返回的函數可以是HandlerFunc

// Now we define a type to implement ServeHTTP: 
type HandlerFunc func(*Conn, *Request) 

ServeHTTP這裏是添加到該類型HandlerFunc的方法:

func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) { 
    f(c, req) // the receiver's a func; call it 
} 

它所做的是調用與給定的參數的函數本身(f)。

// Convert function to attach method, implement the interface: 
var Handle404 = HandlerFunc(notFound); 

在上述線,notFound已經finagled到由出函數本身的人工創建類型實例及其製造功能到該實例的ServeHTTP方法用於爲Handler界面可以接受的。現在Handle404可以與Handler接口一起使用。這基本上是一種伎倆。

+0

好吧我想我現在明白了,絆倒我的東西是notFound到HandlerFunc的轉換。在重讀有效轉換的轉換部分之後,更清楚如何也可以將其應用於函數。 http://golang.org/doc/effective_go.html#conversions – mbarkhau 2009-11-21 15:40:57

1

你對下半場的瞭解究竟是什麼?它與上面的模式相同。它不是將Counter類型定義爲int,而是定義一個名爲notFound的函數。然後,他們創建一個名爲HandlerFunc的函數,該函數接受兩個參數,一個連接和一個請求。然後他們創建一個名爲ServeHTTP的新方法,該方法被綁定到HandlerFunc類型。 Handle404只是這個類的一個使用notFound函數的實例。

+2

是的,這是典型的高階函數式編程。在你第一次看到它並在你的方式中工作時,它可能會讓你感到困惑。 – Suppressingfire 2009-11-21 02:57:40