2009-11-21 49 views
10

Tôi muốn biết điều gì đang xảy ra ở đây.Chức năng thực hiện giao diện

Có giao diện cho một handler http:

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

này thực hiện Tôi nghĩ rằng tôi hiểu.

type Counter int 

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

Từ hiểu biết của tôi, loại "Counter" thực hiện giao diện vì nó có phương thức có chữ ký bắt buộc. Càng xa càng tốt. Sau đó, ví dụ này được đưa ra:

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); 

Ai đó có thể giải thích tại sao hoặc cách các chức năng khác nhau này khớp với nhau?

Trả lời

12

này:

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

nói rằng bất kỳ loại nào đáp ứng các giao diện Handler phải có một phương pháp ServeHTTP. Phần trên sẽ nằm trong gói http.

type Counter int 

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

Điều này đặt phương thức vào loại Bộ đếm tương ứng với ServeHTTP. Đây là một ví dụ tách biệt với những điều sau đây.

Từ sự hiểu biết của tôi nó là loại "Counter" cài đặt giao diện vì nó có một phương pháp mà có chữ ký yêu cầu.

Đúng vậy.

Chức năng sau đây sẽ không tự làm việc như một 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"); 
} 

Phần còn lại của công cụ này chỉ được lắp trên để nó có thể là một Handler.

Trong phần tiếp theo, một HandlerFunc là một chức năng mà phải mất hai đối số, con trỏ đến Conncon trỏ đến Request, và trả về không có gì. Nói cách khác, bất kỳ hàm nào nhận các đối số này và trả về không có gì có thể là HandlerFunc.

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

Đây ServeHTTP là một phương pháp bổ sung vào loại HandlerFunc:

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

Tất cả nó là để gọi hàm riêng của mình (f) với các đối số cho trước.

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

Trong dòng trên, notFound đã được finagled ra đời có thể chấp nhận cho giao diện cho Handler bằng cách tạo ra nhân tạo một trường hợp loại ra khỏi chức năng riêng của mình và làm cho chức năng vào phương pháp ServeHTTP cho ví dụ. Hiện tại, Handle404 có thể được sử dụng với giao diện Handler. Về cơ bản nó là một loại lừa.

+0

Ok Tôi nghĩ rằng tôi nhận được nó ngay bây giờ, điều mà vấp tôi lên là chuyển đổi notFound để HandlerFunc. Sau khi đọc lại phần chuyển đổi có hiệu quả, nó rõ ràng hơn cách mà cũng có thể áp dụng cho các hàm. http://golang.org/doc/effective_go.html#conversions – mbarkhau

1

Chính xác thì bạn không hiểu gì về hiệp hai? Đó là mô hình tương tự như trên. Thay vì xác định kiểu Counter như một int, chúng định nghĩa một hàm gọi là notFound. Sau đó, họ tạo ra một loại chức năng gọi là HandlerFunc có hai tham số, một kết nối và một yêu cầu. sau đó họ tạo ra một phương thức mới gọi là ServeHTTP, được gắn với kiểu HandlerFunc. Handle404 đơn giản là một thể hiện của lớp này sử dụng hàm notFound.

+2

Vâng, đó là chương trình chức năng bậc cao điển hình. Nó có thể gây nhầm lẫn lần đầu tiên bạn nhìn thấy nó và làm việc theo cách của bạn thông qua các loại. – Suppressingfire

Các vấn đề liên quan