Почему так происходит и как делать правильно?
Нет, потому что switch <- ch ждет занчений от канала. Ты туда шлешь 2 значения он их и выбирает. Если бы ты слал что то еще.

https://play.golang.org/p/BbaNt4NZm23

Наверно вы хотели сделать нечто подобное

https://play.golang.org/p/KSGAzw6Olfz
Чтобы получить тот результат, который вы ожидаете, нужно использовать select вместо switch.
Обратите внимание на хороший пример https://tour.golang.org/concurrency/6
Работающий пример вашей реализации
package main

import (
	"log"
	"time"
)

func add(ch chan<- string) {
	for {
		time.Sleep(time.Second * 2)
		ch <- "hi"
	}
}

func exit(ch chan<- string) {
	time.Sleep(time.Second * 5)
	ch <- "close"
}

func main() {
	ch := make(chan string, 1000)

	go add(ch)

	go exit(ch)

LOOP:
	for {
		select {
		case val := <- ch:
			switch val {
			case "close":
				log.Println("Close")
				break LOOP
			case "hi":
				log.Println("Hi")
			}
		default:
			log.Println("Default")
			time.Sleep(time.Second * 1)
		}
	}
}

https://play.golang.org/p/m1R8CXNKEYq