Увеличенные секунды не печатаются

#go

#Вперед

Вопрос:

Я изучаю Google Go (кстати, очень интересно), и первой программой, которую я изучал, была запись в блоге Мэтта Аймонетти:

Реальный параллелизм в 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:

  1. Вы используете fmt.Sprintf , он возвращает строку, на самом деле не печатает ее, вы хотите использовать fmt.Printf
  2. Просто 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 получаем значение, которое мы можем напечатать множеством разных способов.