template.Execute(): 无效的内存地址或空指针解引用

huangapple go评论96阅读模式
英文:

template.Execute(): invalid memory address or nil pointer dereference

问题

我正在尝试使用自定义分隔符的Go html/template。

然而,我可以解析和执行我的 "index.html" 文件,但是当我尝试更改模板的分隔符时,我遇到以下错误:

运行时错误:无效的内存地址或空指针解引用 goroutine

这是我的代码:

package main

import (
    "html/template"
    "net/http"
)

var sherrifTmpl = template.New("test").Delims("{[{", "}]}")

func serveHome(w http.ResponseWriter, r *http.Request) {
    template.Must(sherrifTmpl.ParseFiles("index.html")).Execute(w, r)
}

如果我尝试以下任何一种方式:

package main

import (
    "html/template"
    "net/http"
)

func serveHome(w http.ResponseWriter, r *http.Request) {
    template.Must(template.ParseFiles("index.html")).Execute(w, r)
}

或者:

package main

import (
    "html/template"
    "net/http"
)

var sherrifTmpl = template.New("test").Delims("{[{", "}]}")

func serveHome(w http.ResponseWriter, r *http.Request) {
    template.Must(sherrifTmpl.ParseFiles("{{.Host}}")).Execute(w, r)
}

一切都正常工作。我甚至尝试捕获 ParseFiles 的错误。但是仍然没有运气:

package main

import (
    "html/template"
    "net/http"
)

var sherrifTmpl = template.New("test").Delims("{[{", "}]}")

func serveHome(w http.ResponseWriter, r *http.Request) {
    homeTmpl, err := sherrifTmpl.ParseFiles("index.html")
    if err != nil {
        panic(err)
    }
    homeTmpl.Execute(w, r)
}

我看不出我做错了什么。如果你们中的任何人能帮助我解决这个问题,我将不胜感激。

更新 1:

这是 panic 的信息:

2015/04/13 17:43:35 http: panic serving 127.0.0.1:56634: runtime error: invalid memory address or nil pointer dereference
goroutine 5 [running]:
net/http.func·011()
    /usr/local/go/src/net/http/server.go:1130 +0xbb
html/template.(*Template).escape(0xc20803ad80, 0x0, 0x0)
    /usr/local/go/src/html/template/template.go:59 +0xe4
html/template.(*Template).Execute(0xc20803ad80, 0x7f550e16f420, 0xc20805cd20, 0x7280c0, 0xc208032ea0, 0x0, 0x0)
    /usr/local/go/src/html/template/template.go:75 +0x3d
main.serveHome(0x7f550e16f328, 0xc20805cd20, 0xc208032ea0)
    /home/sasan/Works/Karina/Mobazi/Mon-Panel/routes.go:11 +0x136
net/http.HandlerFunc.ServeHTTP(0x7eb738, 0x7f550e16f328, 0xc20805cd20, 0xc208032ea0)
    /usr/local/go/src/net/http/server.go:1265 +0x41
net/http.(*ServeMux).ServeHTTP(0xc20803a6c0, 0x7f550e16f328, 0xc20805cd20, 0xc208032ea0)
    /usr/local/go/src/net/http/server.go:1541 +0x17d
net/http.serverHandler.ServeHTTP(0xc20805a0c0, 0x7f550e16f328, 0xc20805cd20, 0xc208032ea0)
    /usr/local/go/src/net/http/server.go:1703 +0x19a
net/http.(*conn).serve(0xc20805cc80)
    /usr/local/go/src/net/http/server.go:1204 +0xb57
created by net/http.(*Server).Serve
    /usr/local/go/src/net/http/server.go:1751 +0x35e
英文:

I am trying to use Go html/template with custom delimiters.

However, I can Parse and Execute my "index.html" file, whenever I am trying to change my templates Delimiters I face the following error:

runtime error: invalid memory address or nil pointer dereference goroutine

Here is my code:

package main

import (
        "html/template"
        "net/http"
)

var sherrifTmpl = template.New("test").Delims("{[{", "}]}")

func serveHome(w http.ResponseWriter, r *http.Request) {
        template.Must(sherrifTmpl.ParseFiles("index.html")).Execute(w, r)
}

If I try any of the followings:

package main

import (
        "html/template"
        "net/http"
)

func serveHome(w http.ResponseWriter, r *http.Request) {
        template.Must(template.ParseFiles("index.html")).Execute(w, r)
}

Or:

package main

import (
        "html/template"
        "net/http"
)

var sherrifTmpl = template.New("test").Delims("{[{", "}]}")

func serveHome(w http.ResponseWriter, r *http.Request) {
        template.Must(sherrifTmpl.ParseFiles("{[{.Host}]}")).Execute(w, r)
}

Everything works. I even tried to catch ParseFiles error. But still no luck:

package main

import (
        "html/template"
        "net/http"
)

var sherrifTmpl = template.New("test").Delims("{[{", "}]}")

func serveHome(w http.ResponseWriter, r *http.Request) {
        homeTmpl, err := sherrifTmpl.ParseFiles("index.html")
        if err != nil {
            panic(err)
        }
        homeTmpl.Execute(w, r)
}

I can't see where I am doing wrong. I would be grateful if any of you could help me on this issue.

Update 1:

Here is the panic:

2015/04/13 17:43:35 http: panic serving 127.0.0.1:56634: runtime error: invalid memory address or nil pointer dereference
goroutine 5 [running]:
net/http.func·011()
	/usr/local/go/src/net/http/server.go:1130 +0xbb
html/template.(*Template).escape(0xc20803ad80, 0x0, 0x0)
	/usr/local/go/src/html/template/template.go:59 +0xe4
html/template.(*Template).Execute(0xc20803ad80, 0x7f550e16f420, 0xc20805cd20, 0x7280c0, 0xc208032ea0, 0x0, 0x0)
	/usr/local/go/src/html/template/template.go:75 +0x3d
main.serveHome(0x7f550e16f328, 0xc20805cd20, 0xc208032ea0)
	/home/sasan/Works/Karina/Mobazi/Mon-Panel/routes.go:11 +0x136
net/http.HandlerFunc.ServeHTTP(0x7eb738, 0x7f550e16f328, 0xc20805cd20, 0xc208032ea0)
	/usr/local/go/src/net/http/server.go:1265 +0x41
net/http.(*ServeMux).ServeHTTP(0xc20803a6c0, 0x7f550e16f328, 0xc20805cd20, 0xc208032ea0)
	/usr/local/go/src/net/http/server.go:1541 +0x17d
net/http.serverHandler.ServeHTTP(0xc20805a0c0, 0x7f550e16f328, 0xc20805cd20, 0xc208032ea0)
	/usr/local/go/src/net/http/server.go:1703 +0x19a
net/http.(*conn).serve(0xc20805cc80)
	/usr/local/go/src/net/http/server.go:1204 +0xb57
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:1751 +0x35e

答案1

得分: 8

一个模板实际上可以包含多个要执行的“模板”。在这里,你实际上有两个模板;一个名为“test”的空模板,使用自定义分隔符,和一个名为“index.html”的解析模板。

你可以将第一个模板命名为与你的索引模板相同的名称:

var sherrifTmpl = template.New("index.html").Delims("{[{", "}]}")

或者你可以通过名称调用模板,使用ExecuteTemplate

template.Must(sherrifTmpl.ParseFiles("index.html")).ExecuteTemplate(w, "index.html", r)

在这种情况下,html/template包仍然不应该发生panic。这是一个bug,在go1.5中将被修复(目前在git主分支中已修复)。

英文:

A template may actually contain more than one "template" to execute. Here you actually have 2 templates; a nil template named "test" with custom delimiters, and a parsed template named "index.html".

You can either name the first the same name as your index template

var sherrifTmpl = template.New("index.html").Delims("{[{", "}]}")

or you can call the template by name with ExecuteTemplate

template.Must(sherrifTmpl.ParseFiles("index.html")).ExecuteTemplate(w, "index.html", r)

The html/template package still shouldn't panic in this case. This is a bug that will be fixed in go1.5 (currently fixed in git master).

huangapple
  • 本文由 发表于 2015年4月13日 20:42:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/29605632.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定