안녕하세요. 개발자 모도리입니다.
The Go Programming Language 라는 책으로 Go를 공부하고 있으며, 해당 책의 내용을 요약 정리해서 올리려고 합니다. 저는 번역본을 구매해서 공부하고 있습니다.
//Fetch는 url에서 찾은 내용을 출력합니다.
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os"
)
func main() {
for _, url := range os.Args[1:] {
resp, err := http.Get(url)
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
os.Exit(1)
}
b, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err)
os.Exit(1)
}
fmt.Printf("%s", b)
}
}
예제코드 [ch1/fetch.go]
실행결과
$ go run ch1/fetch.go http://gopl.io > gopl.html
gopl.html 파일을 확인하면 http://gopl.io의 소스코드가 있는 것을 확인할 수 있습니다.
그 외 코드 설명
- Body 스트림은 리소스의 누출을 막기 위해 닫습니다.
- Printf는 표준 출력에 응답을 기록합니다.
// Fetchall은 URL을 병렬로 반입하고 시간과 크기를 보고합니다.
package main
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"time"
)
func main() {
start := time.Now()
ch := make(chan string)
for _, url := range os.Args[1:] {
go fetch(url, ch) // 고루틴 시작
}
for range os.Args[1:] {
fmt.Println(<-ch) // ch 채널에서 수신
}
fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())
}
func fetch(url string, ch chan<- string) {
start := time.Now()
resp, err := http.Get(url)
if err != nil {
ch <- fmt.Sprint(err) // ch 채널로 송신
return
}
nbytes, err := io.Copy(ioutil.Discard, resp.Body)
resp.Body.Close() // 리소스 누출 방지
if err != nil {
ch <- fmt.Sprintf("while reading %s: %v", url, err)
return
}
secs := time.Since(start).Seconds()
ch <- fmt.Sprintf("%.2fs %7d %s", secs, nbytes, url)
}
예제코드 [ch1/fetchall.go]
실행결과
$ go build ch1/fetchall.go
$ ./fetchall https://golang.org http://gopl.io https://godoc.org
0.68s 6815 https://godoc.org
0.84s 4154 http://gopl.io
4.84s 8759 https://golang.org
4.84s elapsed