Go 語言程式設計(4)
americanise.go 示例程式碼:
package main import ( "bufio" "fmt" "io" "io/ioutil" "log" "os" "path/filepath" "regexp" "strings" ) var britishAmerican = "./british-american.txt" func main() { inFilename, outFilename, err := filenameFromCommandLine() if err != nil { fmt.Println(err) os.Exit(1) } inFile, outFile := os.Stdin, os.Stdout if inFilename != "" { if inFile, err = os.Open(inFilename); err != nil { log.Fatal(err) } defer inFile.Close() } if outFilename != "" { if outFile, err = os.Create(outFilename); err != nil { log.Fatal(err) } defer outFile.Close() } if err = americanise(inFile, outFile); err != nil { log.Fatal(err) } } func filenameFromCommandLine() (inFilename, outFilename string, err error) { if len(os.Args) > 1 && (os.Args[1] == "-h" || os.Args[1] == "--help") { err = fmt.Errorf("usage: %s [<]infile.txt [>]outfile.txt", filepath.Base(os.Args[0])) return "", "", err } if len(os.Args) >1 { inFilename = os.Args[1] if len(os.Args) > 2 { outFilename = os.Args[2] } } if inFilename != "" && inFilename == outFilename { log.Fatal("won't overwrite the infile") } return inFilename, outFilename, nil } func americanise(inFile io.Reader, outFile io.Writer) (err error){ reader := bufio.NewReader(inFile) writer := bufio.NewWriter(outFile) defer func() { if err == nil { err = writer.Flush() } }() var replacer func(string) string britishAmericanPath, _ := filepath.Abs(britishAmerican) if replacer, err = makeReplacerFunc(britishAmericanPath); err != nil { return err } wordRx := regexp.MustCompile("[A-Za-z]+") eof := false for !eof { var line string line, err = reader.ReadString('\n') if err == io.EOF { err = nil eof = true } else if err != nil { return err } line = wordRx.ReplaceAllStringFunc(line, replacer) if _, err = writer.WriteString(line); err != nil { return err } } return nil } func makeReplacerFunc(file string) (func(string) string, error) { rawBytes, err := ioutil.ReadFile(file) if err != nil { return nil, err } text := string(rawBytes) usForBritish := make(map[string] string) lines := strings.Split(text, "\n") for _, line := range lines { fields := strings.Fields(line) if len(fields) == 2 { usForBritish[fields[0]] = fields[1] } } return func(word string) string { if usWord, found := usForBritish[word]; found { return usWord } return word }, nil }
知識點:
-
bufio
包實現了有緩衝的I/O。它包裝一個io.Reader或io.Writer介面物件,建立另一個也實現了該介面,且同時還提供了緩衝和一些文字I/O的幫助函式的物件 -
io
包提供了底層的 I/O 功能 -
io/ioutil
包實現了一些 I/O 實用函式 -
regexp
包實現了正則表示式搜尋,和Perl
、Python
等語言的正則基本一致 -
效能對比
bufio
>ioutill
>os
,對於不同的專案,選擇不同的方法 -
panic
是一個執行時錯誤,我們可以通過內建的panic()
函式觸發一個異常,還能使用recover()
函式阻止錯誤的傳遞 -
golang 定義
Map
的方法:
/* 宣告變數,預設 map 是 nil */ var map_variable map[key_data_type]value_data_type /* 使用 make 函式 */ map_variable := make(map[key_data_type]value_data_type)
- 函式可以作為其它函式的引數進行傳遞,然後在其它函式內呼叫執行,一般稱之為回撥
defer 用法:
通過使用defer
修飾一個函式,使其在外部函式 "返回後" 才被執行,即便外部的函式返回的是panic
異常,這類函式被稱作延遲呼叫函式
注意點:
defer defer defer
常見使用場景:
panic