我正在学习Google Go(非常有趣,顺便说一下)和我以前学过的第一个程序是Matt Aimonetti的博客文章:
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)然后转换为字符串?
来打印它这个例子和博客文章中的解释是一次很棒的学习经历!
答案 0 :(得分:3)
问:为什么不打印秒计数器?
答:因为你使用了fmt.Sprintf,它返回一个格式化的字符串;它不会打印该字符串。使用fmt.Printf。
问:如何通过将毫秒转换为秒(作为int)然后转换为字符串来打印它?
答:如果你有一个以毫秒为单位的值,只需除以1000得到秒。 fmt.Printf会将它转换为你的字符串。
答案 1 :(得分:3)
fmt.Sprintf
,它会返回一个字符串,并不会实际打印它,您想使用fmt.Printf
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
值,我们可以通过多种不同方式打印。