Understanding the select statement to not return if something is false


(Pdev Hecht) #1

Hello, I would like to first thank those in the know here are so helpful!

I’m pretty surprised this code works. It take a generated stream and returns the proper values of the bool “if prime”. I would prefer to only print out “prime:X”. For this I have notSmartPrime1, but I have to print “Prime:0” when it isn’t prime. I would rather not print anything at all. Any ideas?

notSmartPrime := func(
    		done <-chan interface{},
    		primeStream <-chan int,
    	) <-chan bool {
    		localStream := make(chan bool)
    		go func() {
    			defer close(localStream)
    			for v := range primeStream {
    				select {
    				case <-done:
    					return
    				case localStream <- isPrime(uint64(v)):
    				}
    			}

    		}()
    		return localStream
    	}

notSmartPrime1 := func(
		done <-chan interface{},
		primeStream <-chan int,
	) <-chan int {
		localStream := make(chan int)
		go func() {
			defer close(localStream)
			localPrime := 0
			for v := range primeStream {
				if isPrime(uint64(v)) {
					localPrime = v
				} else {
					localPrime = 0
				}
				select {
				case <-done:
					return
				case localStream <- localPrime:
				}
			}

		}()
		return localStream
	}

(Christoph Berger) #2

A spontaneous idea (I hope I understood the problem):

select {
	case <-done:
		return
	default:
}
if localPrime != 0 {
	localStream <- localPrime
}

(Pdev Hecht) #3

Thanks! While I used your code and it worked, I was also able to get this to work:

			select {
			case <-done:
				return
			default:
				if localPrime != 0 {
					localStream <- localPrime
				}
			}

It seems the “default:” is critical since with out it I had unreachable code. Such as this:

			select {
			case <-done:
				return
			}

			if localPrime != 0 { // unreachable. 
				localStream <- localPrime
			}

(Christoph Berger) #4

Your observation is correct. Without default, the select statement blocks until one of the cases applies. The default case allows to do something (or simply continue) if none of the other cases apply.