2015-01-16 8 views
2

봐는 결과 나는 빈 출력을 가지고와 time.After에 도달하지 않을 수있는 바와 같이, 다음 코드에서

package main 

import (
    "fmt" 
    "time" 
) 

func sender(ch chan string) { 

    ch <- "Hello" 
    ch <- "Foo" 
    ch <- "and" 
    ch <- "Boo" 
    close(ch) 
} 

func main() { 

    ch := make(chan string) 

    go sender(ch) 

    for { 
     select { 
     case value := <-ch: 
      fmt.Println(value) 
     case <-time.After(time.Second * 2): 
      fmt.Println("Return") 
      return 
     } 
    } 
} 

스 니펫. 왜?

닫힌 채널에서 값을 받으려고하면 해당 유형에서 0 값이 수신됩니다. 닫힌 채널에서 계속 가치를 얻을 수있는 이유는 무엇입니까?

v, ok := <-ch 

확인이 거짓이면 내가 너무 좋아도 확인할 수 있습니다

는 채널이 닫혀 있습니다.

+0

내 프로그램은'송신기에서 전송 단어() '기능을 인쇄하고 그'string'의 값이 0 인 빈 라인 인쇄 유지 한 후,이 제로 값을 반환 . 'close (ch)'를 제거하고 어떤 일이 일어나는지보십시오. – icza

답변

4

for 루프의 모든 반복마다 새로운 2 초 타이머가 생성됩니다. 닫힌 채널은 항상 수신 할 준비가되어 있습니다. 닫힌 채널을 수신 할 준비가되기 전에 새 타이머의 채널을 수신 할 준비가되지 않았기 때문에 코드가 영원히 반복됩니다. 이 문제를 해결하려면

한 가지 방법은 전무에 채널을 설정하는 것입니다 :

case value, ok := <-ch: 
     if !ok { 
      ch = nil 
     } else { 
      fmt.Println(value) 
     } 

이 전무 채널에서 수신

준비 결코 없다.

after := time.After(time.Second * 2) 

를 루프에서이 하나의 타이머를 선택하면 최대 2 초 동안 실행하는 루프를 원하는 경우

playground example

, 당신은 루프의 외부 타이머를 생성해야합니다 :

case <-after: 
     fmt.Println("Return") 
     return 

playground example

01 (수면 놀이터에서 예를 실행할 수 있도록 추가)

채널을 nil로 설정하고 루프 외부에서 타이머를 만들 수 있습니다. 폐쇄 된 채널로부터 수신 할 때

playground example

+0

'닫힌 채널은 항상 수신 할 준비가되어 있습니다. '무엇을 의미합니까? 폐쇄 채널에서 매회받을 수 있습니까? –

+1

@zero_coding 닫힌 채널이 항상 수신 준비가되었다고 말하도록 문장을 업데이트했습니다. 다른 방법으로 말하자면, 닫힌 채널을 수신하지 마십시오. –