在结构中设置值失败

时间:2017-04-18 16:56:46

标签: http go struct

我在结构中设置了值,但未设置。因此调用这些方法,而不是并行调用。怎么可能?这是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

2 个答案:

答案 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
    }
}