0

作为练习,我创建了一个小型 HTTP 服务器,它生成随机游戏机制,类似于这个。我是在 Windows 7(32 位)系统上编写的,它运行良好。但是,当我在家用计算机 Windows 7(64 位)上运行它时,它总是失败并显示相同的消息: exit status -1073741819. 我还没有设法在网上找到任何引用该状态代码的东西,所以我不知道它有多重要。

这是服务器的代码,省略了冗余:

package main

import (
    "fmt"
    "math/rand"
    "time"
    "net/http"
    "html/template"
)

// Info about a game mechanic
type MechanicInfo struct { Name, Desc string }

// Print a mechanic as a string
func (m MechanicInfo) String() string {
    return fmt.Sprintf("%s: %s", m.Name, m.Desc)
}

// A possible game mechanic
var (
    UnkillableObjects = &MechanicInfo{"Avoiding Unkillable Objects",
                                      "There are objects that the player cannot touch. These are different from normal enemies because they cannot be destroyed or moved."}
    //...
    Race              = &MechanicInfo{"Race",
                                      "The player must reach a place before the opponent does. Like \"Timed\" except the enemy as a \"timer\" can be slowed down by the player's actions, or there may be multiple enemies being raced against."}
)

// Slice containing all game mechanics
var GameMechanics []*MechanicInfo

// Pseudorandom number generator
var prng *rand.Rand

// Get a random mechanic
func RandMechanic() *MechanicInfo {
    i := prng.Intn(len(GameMechanics))
    return GameMechanics[i]
}


// Initialize the package
func init() {
    prng = rand.New(rand.NewSource(time.Now().Unix()))

    GameMechanics = make([]*MechanicInfo, 34)
    GameMechanics[0] = UnkillableObjects
    //...
    GameMechanics[33] = Race
}

// serving

var index = template.Must(template.ParseFiles(
    "templates/_base.html",
    "templates/index.html",
))

func randMechHandler(w http.ResponseWriter, req *http.Request) {
    mechanics := [3]*MechanicInfo{RandMechanic(), RandMechanic(), RandMechanic()}
    if err := index.Execute(w, mechanics); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func main() {
    http.HandleFunc("/", randMechHandler)
    if err := http.ListenAndServe(":80", nil); err != nil {
        panic(err)
    }
}

此外,未删节的代码_base.html 模板index.html 模板

什么可能导致此问题?是否有调试这样的神秘退出状态的过程?

4

1 回答 1

1

当我运行它时,我收到以下两个错误:

template: content:6: nil pointer evaluating *main.MechanicInfo.Name
http: multiple response.WriteHeader calls

前者在网络浏览器中,后者在我启动服务器的控制台窗口中。

nil 指针问题是因为您的删节程序将 GameMechanics[1:32] 设置为 nil。

第二个错误很有趣。在您的程序中,您的 http.ResponseWriter 上的任何方法都被调用的唯一位置是 index.Execute 内部,这不是您的代码——这意味着可能在 html/template 中发生了错误。我正在使用 Go 1.0.2 对此进行测试。

我将 _base.html 放在 index.html 的顶部,然后将 index 更改为:

var index = template.Must(template.ParseFiles("templates/index.html"))

并且 http.WriteHeaders 警告消失了。

不是真正的答案,而是您可以探索的方向。

作为奖励,这是编写程序的更多“Go方式”。请注意,我简化了 PRNG 的使用(您不需要实例化,除非您想要几个并行)并简化了结构初始化程序:

package main

import (
    "fmt"
    "html/template"
    "math/rand"
    "net/http"
)

// Info about a game mechanic
type MechanicInfo struct{ Name, Desc string }

// Print a mechanic as a string
func (m MechanicInfo) String() string {
    return fmt.Sprintf("%s: %s", m.Name, m.Desc)
}

// The game mechanics
var GameMechanics = [...]*MechanicInfo{
    {"Avoiding Unkillable Objects",
        "There are objects that the player cannot touch. These are different from normal enemies because they cannot be destroyed or moved."},
    {"Race",
        "The player must reach a place before the opponent does. Like \"Timed\" except the enemy as a \"timer\" can be slowed down by the player's actions, or there may be multiple enemies being raced against."},
}

// Get a random mechanic
func RandMechanic() *MechanicInfo {
    i := rand.Intn(len(GameMechanics))
    return GameMechanics[i]
}

var index = template.Must(template.ParseFiles("templates/index.html"))

func randMechHandler(w http.ResponseWriter, req *http.Request) {
    mechanics := [3]*MechanicInfo{RandMechanic(), RandMechanic(), RandMechanic()}
    if err := index.Execute(w, mechanics); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func main() {
    http.HandleFunc("/", randMechHandler)
    if err := http.ListenAndServe(":80", nil); err != nil {
        panic(err)
    }
}
于 2012-08-28T15:36:23.523 回答