2012-04-08 66 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(该函数将是一个闭包)。