Когда вы запускаете обычную программу, она ожидает ввода от канала. И поскольку существует только одна процедура, нет способа получить входные данные из канала (нет другого потока для отправки на него). Таким образом, тупик сообщается.
С другой стороны, для выполнения тестов для выполнения тестов используются программы. Таким образом, появляется более одной программы, и тупик не обнаружен (среда выполнения предполагает, что другая программа может отправить на канал).
Чтобы ответить на ваш вопрос из комментария: go run и go test не являются должен достичь того же эффекта. go run выполняет вашу программу, go test выполняет процедуры, которые проверяют ваш код. Эти команды выполняют две разные программы.
Я не уверен, что вы можете обнаружить подобные ошибки (взаимоблокировки) с помощью тестов.
Редактировать: go test
ожидает завершения теста sh ( Вы можете настроить как долго с опцией -timeout d
). Поэтому я предполагаю, что он порождает программу, ожидающую истечения срока действия timer.Timer
, поэтому нет тупика (всегда есть одна программа, которая может быть выполнена).
Edit2: Try эта программа:
package main
import (
"fmt"
"time"
)
func main() {
go func() {
t := time.NewTimer(10 * time.Second)
<-t.C
}()
fmt.Println("hello")
ch := make(chan struct{}, 1)
<-ch
}
Она ожидает 10 секунд, прежде чем сообщать о взаимоблокировке.
Edit3: Или взгляните на текущий код, который иллюстрирует работу тестового прогона:
package main
import (
"fmt"
"time"
)
func original_main_func() {
fmt.Println("hello")
ch := make(chan struct{}, 1)
<-ch
}
func test() {
original_main_func()
}
func test_runner() {
ch := make(chan struct{}, 1)
go func() {
test()
close(ch)
}()
t := time.NewTimer(10 * time.Second)
select {
case <-t.C:
panic("timeout")
case <-ch:
fmt.Println("test executed")
}
}
func main() {
test_runner()
}