2012-04-08 68 views
1

我試圖使用svgo package在svg文件上繪製點並顯示使用Web瀏覽器的點。從查看net/http文檔,我不知道如何將參數傳遞給我的svgWeb函數。將參數傳遞到HandlerFunc

以下示例在我的Web瀏覽器中編譯並顯示一個三角形和一條線,但我真正想要做的是使用Polyline方法繪製xpts和ypts。我如何通過適當的論據或重構這個例子來完成這個任務?

package main 

import (
    "github.com/ajstarks/svgo" 
    "log" 
    "net/http" 
) 

func svgWeb(w http.ResponseWriter, req *http.Request) { 
    w.Header().Set("Content-Type", "image/svg+xml") 

    xpts := []int{1, 200, 5} 
    ypts := []int{200, 400, 300} 
    s := svg.New(w) 
    s.Start(500, 500) 
    s.Line(5, 10, 400, 400, "stroke:black") 
    s.Polyline(xpts, ypts, "stroke:black") 
    s.End() 
} 

//// Main Program function 
////////////////////////////// 

func main() { 

    xpts := []int{} 
    ypts := []int{} 

    for i := 0; i < 100; i++ { 
     xpts = append(xpts, i) 
     xpts = append(ypts, i+5) 
    } 

    http.Handle("/economy", http.HandlerFunc(svgWeb)) 
    err := http.ListenAndServe(":2003", nil) 
    if err != nil { 
     log.Fatal("ListenAndServe:", err) 
    } 
} 
+1

我很困惑。如果你使用'net/http'來創建一個處理程序,爲什麼你不能從處理程序中的'http.request'獲取你的參數?用途是什麼? – jdi 2012-04-08 23:45:05

回答

2

如果您的參數是由客戶提供的,那麼他們應該通過http.Request傳遞給您的處理程序。

但是,如果你想要做的是驅動你的svgWeb處理程序不是由客戶端請求提供的點,而是由應用程序中的一些其他函數在內部生成這些值,那麼一種方法是構造您的處理程序放入結構中並使用成員屬性。

的結構可以是這樣的:

type SvgManager struct { 
    Xpts, Ypts []int 
} 

func (m *SvgManager) SvgWeb(w http.ResponseWriter, req *http.Request) { 
    w.Header().Set("Content-Type", "image/svg+xml") 

    s := svg.New(w) 
    s.Start(500, 500) 
    s.Line(5, 10, 400, 400, "stroke:black") 
    s.Polyline(m.Xpts, m.Ypts, "stroke:black") 
    s.End() 
} 

然後在你的主:

manager := new(SvgManager) 

for i := 0; i < 100; i++ { 
    manager.Xpts = append(manager.Xpts, i) 
    manager.Ypts = append(manager.Ypts, i+5) 
} 

// I only did this assignment to make the SO display shorter in width. 
// Could have put it directly in the http.Handle() 
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 
    manager.SvgWeb(w, req) 
}) 
http.Handle("/economy", handler) 

現在你有可能含有其他處理程序,以及一個SvgManager實例,可以更新影響他們的處理程序的輸出。

通過滿足Handler interface

正如意見中提到的@Atom,你完全可以通過簡單地重命名你的方法,以避免ServeHTTP關閉和包裝。這將滿足Handler interface

func (m *SvgManager) ServeHTTP(w http.ResponseWriter, req *http.Request) { 
    ... 

manager := new(SvgManager) 
http.Handle("/economy", manager) 
+2

如果SvgManager的方法'SvgWeb'被重命名爲'ServeHTTP',那麼SvgManager實現'net/http.Handler'接口,它可以直接傳遞給'http.Handle'。 – 2012-04-09 08:35:14

+0

@Atom:很好的電話。我會補充一點 – jdi 2012-04-09 16:09:29

1

您應該將main中的函數定義爲匿名函數。這樣,它可以引用局部變量xptsypts(該函數將是一個閉包)。