为什么goroutine阻止此HTTP服务器中的main func?

I want to setup a http server with httprouter listening on two ports 8888 and 8080 just like the code below.

package main

import (
    "fmt"
    "github.com/julienschmidt/httprouter"
    "log"
    "net/http"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    fmt.Fprint(w, "Welcome!
")
}

func main() {
    router := httprouter.New()
    router.GET("/", Index)

    fmt.Println("listen on 8080")
    // this is where blocked
    go log.Fatal(http.ListenAndServe(":8080", router))
    fmt.Println("listen on 8888")
    log.Fatal(http.ListenAndServe(":8888", router))
}

But it doesn't work properly,my server only listen on 8080.If I make some change:

go func() { log.Fatal(http.ListenAndServe(":8080", router)) }()

It works finely both on 8080 and 8888.So why? It's about closure or something else?

The function value and parameters are evaluated as usual in the calling goroutine

Go language spec, "Go statements".

You're creating a goroutine for the call to log.Fatal, but the arguments to log.Fatal are evaluated beforehand, in the main goroutine. And Fatal's argument is the return value of http.ListenAndServe. So the new goroutine doesn't start until after ListenAndServe returns.

Try this.

The first http.ListenAndServe statement should be placed inside function. That is one of the example how to execute block of statements as goroutine, just wrap it inside a function then call it.

Keep the second listen as it is, it's need to be blocking.

func main() {
    router := httprouter.New()
    router.GET("/", Index)

    go func() {
        fmt.Println("listen on 8080")
        log.Fatal(http.ListenAndServe(":8080", router))
    }()

    fmt.Println("listen on 8888")
    log.Fatal(http.ListenAndServe(":8888", router))
}