#go
#Вперед
Вопрос:
Я изучаю Google Go (кстати, очень интересно), и первой программой, которую я изучал, была запись в блоге Мэтта Аймонетти:
package main
import (
"fmt"
"net/http"
"time"
)
var urls = [] string {
"http://golang.org",
"http://www.espn.com",
"http://www.google.com",
}
type HttpResponse struct {
url string
response *http.Response
err error
}
func asyncHttpGets(urls [] string) [] *HttpResponse {
ch := make(chan *HttpResponse)
responses := [] *HttpResponse{}
seconds := 0
for _, url := range urls {
go func(url string) {
fmt.Printf("Fetching %s n", url)
resp, err := http.Get(url)
ch <- amp;HttpResponse{url, resp, err}
}(url)
}
for {
select {
case r := <-ch:
fmt.Printf("%s was fetchedn", r.url)
responses = append(responses, r)
if len(responses) == len(urls) {
return responses
}
case <- time.After(50 * time.Millisecond):
seconds
fmt.Printf(".")
fmt.Sprintf("%v", seconds)
}
}
return responses
}
func main() {
results := asyncHttpGets(urls)
for _, result := range results {
fmt.Printf("%s status: %sn", result.url, result.response.Status)
}
}
Я хотел, чтобы миллисекунды также печатались в выходных данных, поэтому я создал переменную seconds внутри метода asyncHttpGets и увеличил ее в том же месте, где печатается «.»
Однако он никогда не отображается при запуске:
go build concurrency_example.go amp;amp; ./concurrency_example
Выводит:
Fetching http://golang.org
Fetching http://www.espn.com
Fetching http://www.google.com
...http://www.google.com was fetched
..http://golang.org was fetched
.........http://www.espn.com was fetched
http://www.google.com status: 200 OK
http://golang.org status: 200 OK
http://www.espn.com status: 200 OK
Вопрос (ы):
Почему не печатается счетчик секунд?
Как мне распечатать его, преобразовав миллисекунды в секунды (как int), а затем преобразовать в строку?
Этот пример и пояснения в сообщении в блоге были отличным опытом обучения!
Ответ №1:
Вопрос: Почему не печатается счетчик секунд?
Ответ: Потому что вы использовали fmt.Sprintf , который возвращает форматированную строку; он не печатает эту строку. Используйте fmt.Printf.
Вопрос: Как мне распечатать его, преобразовав миллисекунды в секунды (как int), а затем преобразовать в строку?
О: Если у вас есть значение в миллисекундах, просто разделите на 1000, чтобы получить seconds. fmt.Printf преобразует его в строку для вас.
Ответ №2:
- Вы используете
fmt.Sprintf
, он возвращает строку, на самом деле не печатает ее, вы хотите использоватьfmt.Printf
- Просто
fmt.Println(ms/1000)
напечатает секунды.
Комментарии:
1. При попытке fmt. При печати (секунды / 1000) я получил следующую ошибку: невозможно использовать секунды / 1000 (тип int) в качестве строки типа в аргументе функции. Это первоначальная причина, по которой я нашел Sprintf после того, как я погуглил эту ошибку. Кроме того, автор ничему не назначал время, как я могу присвоить его чему-либо (чтобы полностью исключить целое число секунд)?
2. Если вы хотите
printf
использовать:fmt.Printf("%dn", seconds / 1000)
, проверьте ссылку в моем ответе.
Ответ №3:
Как упоминали другие, проблема заключается в том, что вы использовали fmt.Sprintf, который форматирует строку в соответствии с форматом (первый аргумент вызова функции).
Замените fmt.Sprintf("%v", seconds)
на fmt.Printf("%vn", seconds)
, чтобы напечатать добавочное значение или fmt.Printf("%vn", seconds/1000)
если вы хотите напечатать миллисекунды. Тем не менее, лучшим / более точным способом получения времени, прошедшего между запуском функции, и когда время печатает время, было бы использовать time
пакет, как показано ниже:
package main
import (
"fmt"
"net/http"
"time"
)
var urls = []string{
"http://golang.org",
"http://www.espn.com",
"http://www.google.com",
}
type HttpResponse struct {
url string
response *http.Response
err error
}
func asyncHttpGets(urls []string) []*HttpResponse {
ch := make(chan *HttpResponse)
responses := []*HttpResponse{}
for _, url := range urls {
go func(url string) {
fmt.Printf("Fetching %s n", url)
resp, err := http.Get(url)
ch <- amp;HttpResponse{url, resp, err}
}(url)
}
start := time.Now()
for {
select {
case r := <-ch:
fmt.Printf("%s was fetchedn", r.url)
responses = append(responses, r)
if len(responses) == len(urls) {
return responses
}
case t := <-time.After(50 * time.Millisecond):
fmt.Println(t.Sub(start))
}
}
return responses
}
func main() {
results := asyncHttpGets(urls)
for _, result := range results {
fmt.Printf("%s status: %sn", result.url, result.response.Status)
}
}
Мы собираем выходные данные таймера, возвращаемые time.After
и вычитаем время начала, которое мы устанавливаем при вызове функции. В итоге мы time.Duration
получаем значение, которое мы можем напечатать множеством разных способов.