我正在尝试使用svgo package在svg文件上绘制点并使用Web浏览器显示它。通过查看net/http
文档,我不知道如何将参数传递到我的svgWeb
函数中。
以下示例在我的网络浏览器中编译并显示一个三角形和一条线,但我真正想要做的是使用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)
}
}
答案 0 :(得分: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实例,并且可以更新它以影响其处理程序的输出。
正如@Atom在评论中所提到的,只需将方法重命名为ServeHTTP,就可以完全避免闭包和包装。这将满足Handler interface
func (m *SvgManager) ServeHTTP(w http.ResponseWriter, req *http.Request) {
...
manager := new(SvgManager)
http.Handle("/economy", manager)
答案 1 :(得分:1)
您应该将main
内的函数定义为匿名函数。这样,它可以引用局部变量xpts
和ypts
(函数将是一个闭包)。