<p dir="auto">The following program leaves a hanged goroutine. If a server reloads templates on the fly, this behavior can leads to unbounded number of leaked goroutines.</p>
<div class="highlight highlight-source-go notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="package main

import (
    &quot;html/template&quot;
    &quot;time&quot;
)

func main() {
    template.New(&quot;foo&quot;).Parse(&quot;{{.&quot;)
    time.Sleep(time.Second)
    panic(&quot;who's there?&quot;)
}"><pre class="notranslate"><span class="pl-k">package</span> main

<span class="pl-k">import</span> (
    <span class="pl-s">"html/template"</span>
    <span class="pl-s">"time"</span>
)

<span class="pl-k">func</span> <span class="pl-en">main</span>() {
    <span class="pl-s1">template</span>.<span class="pl-en">New</span>(<span class="pl-s">"foo"</span>).<span class="pl-en">Parse</span>(<span class="pl-s">"{{."</span>)
    <span class="pl-s1">time</span>.<span class="pl-en">Sleep</span>(<span class="pl-s1">time</span>.<span class="pl-c1">Second</span>)
    <span class="pl-en">panic</span>(<span class="pl-s">"who's there?"</span>)
}</pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="panic: who's there?

goroutine 1 [running]:
main.main()
    /tmp/htmltempl.go:11 +0x297

goroutine 5 [chan send]:
text/template/parse.(*lexer).errorf(0xc2080c2000, 0x5d8290, 0xf, 0x0, 0x0, 0x0, 0xffffff01)
    src/text/template/parse/lex.go:165 +0xca
text/template/parse.lexInsideAction(0xc2080c2000, 0x623b78)
    src/text/template/parse/lex.go:280 +0xaf7
text/template/parse.(*lexer).run(0xc2080c2000)
    src/text/template/parse/lex.go:198 +0x5d
created by text/template/parse.lex
    src/text/template/parse/lex.go:191 +0x1b9"><pre class="notranslate"><code class="notranslate">panic: who's there?

goroutine 1 [running]:
main.main()
    /tmp/htmltempl.go:11 +0x297

goroutine 5 [chan send]:
text/template/parse.(*lexer).errorf(0xc2080c2000, 0x5d8290, 0xf, 0x0, 0x0, 0x0, 0xffffff01)
    src/text/template/parse/lex.go:165 +0xca
text/template/parse.lexInsideAction(0xc2080c2000, 0x623b78)
    src/text/template/parse/lex.go:280 +0xaf7
text/template/parse.(*lexer).run(0xc2080c2000)
    src/text/template/parse/lex.go:198 +0x5d
created by text/template/parse.lex
    src/text/template/parse/lex.go:191 +0x1b9
</code></pre></div>
<p dir="auto">on commit <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/golang/go/commit/ccc76dba606e2325ad82ac0b15fb5c511a342abd/hovercard" href="https://github.com/golang/go/commit/ccc76dba606e2325ad82ac0b15fb5c511a342abd"><tt>ccc76db</tt></a></p>
<pre class="notranslate">Here is a nice trick to write an enum-like type's constant values:

g% cat x.go
package p

type T int

const (
    _ T = iota
    T1
    T2
    T3
    T4
)
g% 

This has two properties I wanted: (1) the values start at 1, so the zero value is not a
defined value, and (2) all the defined values have the same form on the line, so that I
can pipe them through 'sort' without breaking anything. Compare to

const (
    X T = 1 + iota
    Y
    Z
)

Anyway, this _ trick works well for me.

It works less well for godoc:

g% godoc .
PACKAGE DOCUMENTATION

package p
    import "."


CONSTANTS

const (
    T1
    T2
    T3
    T4
)

TYPES

type T int


g% 

It's a bit confusing that you can't see the _ in the godoc output, since the _ is what
defines the type and value of the constants.

Worse, the constants are not attached to the type T like they normally would be:

g% godoc . T
type T int


g% 

If I rename the _ to Dummy, then it works:

g% godoc . T
type T int

const (
    Dummy T = iota
    T1
    T2
    T3
    T4
)


g% 

What's happening here is that _ is treated as unexported and so it filters away.
(Renaming to dummy shows the same behavior as _.)

Perhaps the best fix would be to treat _ as exported for the purposes of godoc filtering
in const lists and possibly also struct fields (where _ is often padding).

I thought about saying that _ should be treated as exported for all filtering, but you
probably don't want to show things like

func _() { ... }
var _ Interface = (*Type)(nil)</pre>