2017-04-18 34 views
1

我在結構中設置了值,但未設置值。該方法被稱爲因此,不能並行。怎麼可能?這是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 
+3

如果你想有一個方法來修改它的接收器,你需要定義對接收器的指針https://tour.golang.org該方法的價值/方法/ 4 – mkopriva

+0

OMG,謝謝。我知道,但我總是莫名其妙地忘記它。 XD與零相同,是數組中的第一個索引。我總是想從1開始寫循環而不是0 XD – Chelovek

回答

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結構的相同副本工作,將在其字段共享價值觀。

+0

。謝謝。 – Chelovek

1

如果你看看文檔爲http.Server你會看到一個空值是可能的,意思是「:HTTP」:

type Server struct { 
     Addr  string  // TCP address to listen on, ":http" if empty 

您可以直接在init()設置srv.server.Addr,但這不是正確的方法使用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 
    } 
}