這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
對於語言設計之爭, 唯一需要牢記的一句話是: 如果把 C 變成 C++, 那麼 C 就消失了。
Go 是一個輕量級的簡潔的支援並發的語言, 可以用於探索性個人項目, 這是我想學這門語言的主要原因。 對於有一定編程經驗的人來說, 學習一種新語言的方式是, 先概覽下語言特性, 然後編寫一個中等規模的程式, 儘可能地運用到大部分重要特性。
下面的程式用於計算一個目錄下所有檔案或目錄的大小。
package mainimport ( "fmt" "time" "os" "log")type ShortFileInfo struct {fileName stringsize int64}func (fileInfo *ShortFileInfo) Desc() string { return fmt.Sprintf("{%s:%d}", fileInfo.fileName, fileInfo.size)}func produceFiles(dirName string) []os.FileInfo { path, err := os.Open(dirName) if err != nil { log.Fatal(err) } defer path.Close()fileInfos, err := path.Readdir(0);if err != nil { log.Fatal(err)} return fileInfos;}func procFile(fileInfo os.FileInfo, baseDirName string, channelBuffer chan ShortFileInfo) {var filesize int64fileName := fileInfo.Name()if fileInfo.IsDir() {filesize = totalFilesizeInDir(fileInfo, baseDirName)} else {filesize = fileInfo.Size() } shortFileInfo := ShortFileInfo{fileName, filesize};fmt.Println(time.Now().String() + " store: " + shortFileInfo.Desc()) channelBuffer <- shortFileInfo }func totalFilesizeInDir(fileInfo os.FileInfo, baseDirName string) int64 {var filesize int64 = 0fileInfos := produceFiles(baseDirName + "\\" + fileInfo.Name())for _, subfileInfo := range fileInfos {if subfileInfo.IsDir() {filesize += totalFilesizeInDir(subfileInfo, baseDirName + "\\" + fileInfo.Name())} else {filesize += subfileInfo.Size()}}return filesize}func sleep(ns int) {time.Sleep(time.Duration(time.Second)*time.Duration(ns))}const (B int64 = 1KB int64 = 1024MB int64 = 1024*1024GB int64 = 1024*1024*1024TB int64 = 1024*1024*1024*1024)const formatF string = "%8.4f" func readableSize(sizeInBytes int64) string {switch {case B <= sizeInBytes && sizeInBytes < KB:return fmt.Sprintf("%dB", sizeInBytes)case KB <= sizeInBytes && sizeInBytes < MB:return fmt.Sprintf(formatF+"KB", float64(sizeInBytes)/float64(KB))case MB <= sizeInBytes && sizeInBytes < GB:return fmt.Sprintf(formatF+"MB", float64(sizeInBytes)/float64(MB))case GB <= sizeInBytes && sizeInBytes < TB:return fmt.Sprintf(formatF+"GB", float64(sizeInBytes)/float64(GB))case TB <= sizeInBytes:return fmt.Sprintf(formatF+"TB", float64(sizeInBytes)/float64(TB))default:return "0"}}func main() { baseDirName := "C:\\Users\\qin.shuq\\Desktop" fileList := produceFiles(baseDirName) fileNumber := len(fileList) channelBuffer := make(chan ShortFileInfo, fileNumber) fileInfoMap := make(map[string] int64, fileNumber) for _, fileInfo := range fileList { go procFile(fileInfo, baseDirName, channelBuffer) } for count := 0 ; count <= fileNumber ; {select {case fileInfo := <- channelBuffer: fmt.Println(time.Now().String() + " fetch: " + fileInfo.Desc())fileInfoMap[fileInfo.fileName] = fileInfo.sizecount++default:if count == fileNumber {close(channelBuffer)}fmt.Println("Waiting for data ...")sleep(2)}}var totalSize int64 totalSize = 0for _ , filesize := range fileInfoMap {totalSize += filesize}fmt.Printf("Total size in %s:%dB %s", baseDirName , totalSize, readableSize(totalSize));}