2016-07-14 5 views
0

어떻게 든 배열의 값에 액세스 할 수 없습니다. 다음은 배열의 선언 방법입니다.go, 배열 반복 반복 중

messages := strings.Split(request_string, end_of_message_terminator) 

그러나이 배열을 통해 루프를 만들 때 값으로 빈 문자열이 생깁니다. 즉, 루프입니다 :

for i, v := range messages { 
    fmt.Printf("messages are (3) %q\n", messages) 
    go func(){ 

     fmt.Printf("message is %s\n", messages[i]) 
     fmt.Printf("i is %s\n", i) 
     fmt.Printf("v is %s\n", v) 
     respond_to_message(messages[i], response_writer()) 
    }() 


} 

그리고 그 출력의 :

messages are (3) ["asti" ""] 
messages are (3) ["asti" ""] 
message is     
i is %!s(int=1)    
v is       
message is     
i is %!s(int=1)    
v is    

사람이 문제가 무엇인지 알고 있나요? 이 슬라이스의 개별 값에 액세스 할 수있는 이유는 무엇입니까? 모두를 시작한 후 (마지막으로, 다음

netcat -l -p 8000 

을 그리고 : 먼저이 프로그램을 실행해야

package main 


import (
    "fmt" 
    "net" 
    "os" 
    "strings" 
// "io/ioutil" 


) 


func main() { 

    end_of_message_terminator := "||" 
    beginning_of_next_message := "" 
    request := make([]byte, 512) 

    service_port := ":7777" 
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service_port) 
    checkError(err) 
    listener, err := net.ListenTCP("tcp", tcpAddr) 
    checkError(err) 



    for { 
     conn, err := listener.Accept() 

     if err != nil { 

      continue 

     } 

     read_len, err := conn.Read(request) 

     if read_len == 0 { 
      continue 
     } 

     request_string := string(request[:read_len]) 
     fmt.Printf("Request String '%s'\n", request_string) 

     messages := strings.Split(request_string, end_of_message_terminator) 
     fmt.Printf("messages are (1) %q\n", messages) 

     messages[0] = beginning_of_next_message + messages[0] 

     if messages[len(messages) - 1] != "" { 
      beginning_of_next_message = messages[len(messages) - 1] 
      messages[len(messages) - 1] = "" 

     } 

     if len(messages) == 1 { 
      continue 
     } 

     fmt.Printf("messages are (2) %q\n", messages) 
     for i, v := range messages { 
      fmt.Printf("messages are (3) %q\n", messages) 
      go func(){ 

       fmt.Printf("message is %s\n", messages[i]) 
       fmt.Printf("i is %s\n", i) 
       fmt.Printf("v is %s\n", v) 

      }() 


     } 
     conn.Close() 

    } 

} 






func checkError(err error) { 

    if err != nil { 

     fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) 
     os.Exit(1) 

    } 

} 

:

는이 코드를 실행하려면 그냥 경우에, 여기에 전체 프로그램입니다 이 프로그램은 실행해야합니다) netcat -l -p 8000을 실행 : 당신의 goroutine에서

printf "asti||" | netcat localhost 7777 
+2

https://github.com/golang/go/wiki/CommonMostakes – squiguy

+1

https://golang.org/doc/faq#closures_and_goroutines – JimB

답변

2

당신이되지 않습니다 제대로 i 바인딩 :

for i, v := range messages { 
    fmt.Printf("messages are (3) %q\n", messages) 
    go func(i int){ 

     fmt.Printf("message is %s\n", messages[i]) 
     fmt.Printf("i is %s\n", i) 
     fmt.Printf("v is %s\n", v) 
     respond_to_message(messages[i], response_writer()) 
    }(i) // you'll have to pass i here 
} 

당신 때문에 각 i의 값이이 경우에 2 - 1 = 1messages[1] == ""

그래서 각 goroutine이 messages[1] 인쇄되는 값입니다 len(messages) - 1로 설정됩니다에 대한 모든 출력이 표시되지 않는 빈 문자열입니다.

+0

정답이지만 잘못된 이유 - 'i'가 'len' (메시지) - 1'. 'i'를 통해 닫힌 모든 goroutine을 큐에 넣었을 때, 루프가 끝날 때까지 실행되지 않으면'i'는 여전히 루프의 마지막 반복에서 값을 얻었 기 때문입니다. 만약 당신이 (클로저가 즉시 실행되도록)'go'를 제거했다면, 예상되는 동작을 찾을 수는 있지만 동시성은 발견 할 수 없습니다. – Adrian