增加的秒数不打印

时间:2014-06-15 00:31:27

标签: go

我正在学习Google Go(非常有趣,顺便说一下)和我以前学过的第一个程序是Matt Aimonetti的博客文章:

Real life concurrency in 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 <- &HttpResponse{url, resp, err}
        }(url)
    }

    for {
        select {
        case r := <-ch:
            fmt.Printf("%s was fetched\n", 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: %s\n", result.url, result.response.Status)
    }
}

我想看到输出中还打印了毫秒,所以我在asyncHttpGets方法中创建了一个秒变量,并在打印“。”的相同位置增加了它。

但是,它在我运行时从不显示:

 go build concurrency_example.go && ./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

问题(S):

为什么不打印秒计数器?

如何通过将毫秒转换为秒(作为int)然后转换为字符串?

来打印它

这个例子和博客文章中的解释是一次很棒的学习经历!

3 个答案:

答案 0 :(得分:3)

问:为什么不打印秒计数器?

答:因为你使用了fmt.Sprintf,它返回一个格式化的字符串;它不会打印该字符串。使用fmt.Printf。

问:如何通过将毫秒转换为秒(作为int)然后转换为字符串来打印它?

答:如果你有一个以毫秒为单位的值,只需除以1000得到秒。 fmt.Printf会将它转换为你的字符串。

答案 1 :(得分:3)

  1. 您正在使用fmt.Sprintf,它会返回一个字符串,并不会实际打印它,您想使用fmt.Printf
  2. 只需fmt.Println(ms/1000)即可打印秒数。

答案 2 :(得分:1)

正如其他人提到的那样,问题是您使用fmt.Sprintf根据格式(函数调用的第一个参数)格式化字符串。

fmt.Sprintf("%v", seconds)替换为fmt.Printf("%v\n", seconds)以打印增量值,如果要打印毫秒,则替换为fmt.Printf("%v\n", 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 <- &HttpResponse{url, resp, err}
    }(url)
  }
  start := time.Now()

  for {
    select {
    case r := <-ch:
      fmt.Printf("%s was fetched\n", 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: %s\n", result.url, result.response.Status)
  }
}

我们正在收集time.After返回的计时器输出,并减去调用该函数时设置的开始时间。我们最终得到time.Duration值,我们可以通过多种不同方式打印。