我在结构中设置了值,但未设置。因此调用这些方法,而不是并行调用。怎么可能?这是golang,忘了说。
如果我在“start”方法(而不是“init”方法)中将代码更改为设置值,则可以正常工作;但是“init”方法中的设置值失败。看起来很奇怪。
package main
import (
"log"
"net/http"
"time"
)
type tServer struct {
ipAddress string
port string
server http.Server
}
var server tServer
func main() {
server.ipAddress = "0.0.0.0"
server.port = "12345"
server.init()
server.start()
time.Sleep(time.Second * 5)
}
func (srv tServer) init() {
srv.server.Addr = srv.ipAddress + ":" + srv.port
log.Println("srv.server.Addr=", srv.server.Addr) ////////////////////
}
func (srv tServer) start() {
log.Println("srv.server.Addr=", srv.server.Addr) ////////////////////
go srv.startServerRoutine()
}
func (srv tServer) startServerRoutine() {
log.Println("Server started at", srv.server.Addr) //
err := srv.server.ListenAndServe()
if err != nil {
log.Println("Server Error:", err) //
return
}
}
这是控制台:
2017/04/18 19:43:07 srv.server.Addr= 0.0.0.0:12345
2017/04/18 19:43:07 srv.server.Addr=
2017/04/18 19:43:07 Server started at
2017/04/18 19:43:07 Server Error: listen tcp :80: bind: permission denied
答案 0 :(得分:5)
这是由于方法的原型:
func (srv tServer) init()
// ^^^ copies values
这样:
server.init() // updates its own copy of server,
// copy gets disposed after init() returns
server.start() // uses its own copy of server
您需要通过指针传递srv
:
func (srv *tServer) init()
在这种情况下,init()
和start()
调用都将在tServer
结构的同一副本上运行,并将在其字段中共享值。
答案 1 :(得分:1)
如果查看http.Server的文档,您会看到一个空白值,并且意味着“:http”:
type Server struct {
Addr string // TCP address to listen on, ":http" if empty
您可以直接在srv.server.Addr
中设置init()
,但这不是使用http.Server
类型的正确方法。
也许你打算这样做:
func (srv tServer) startServerRoutine() {
log.Println("Server started at", srv.ipAddress + ":" + srv.port) //
err := srv.server.ListenAndServe(srv.ipAddress + ":" + srv.port)
if err != nil {
log.Println("Server Error:", err) //
return
}
}