• 《go语言程序设计》学习(三)


    一,单词替换

      1 package main
      2 
      3 import (
      4     "bufio"
      5     "fmt"
      6     "io"
      7     "io/ioutil"
      8     "log"
      9     "os"
     10     "path/filepath"
     11     "regexp"
     12     "strings"
     13 )
     14 
     15 var britishAmerican = "british-american.txt"
     16 
     17 func init() {
     18     dir, _ := filepath.Split(os.Args[0])
     19     britishAmerican = filepath.Join(dir, britishAmerican)
     20     //fmt.Println("dir %s,file %s",dir,britishAmerican)
     21 }
     22 
     23 func main() {
     24     inFilename, outFilename, err := filenamesFromCommandLine()
     25     if err != nil {
     26         fmt.Println(err)
     27         os.Exit(1)
     28     }
     29     inFile, outFile := os.Stdin, os.Stdout
     30     if inFilename != "" {
     31         if inFile, err = os.Open(inFilename); err != nil {
     32             log.Fatal(err)
     33         }
     34         defer inFile.Close()
     35     }
     36     if outFilename != "" {
     37         if outFile, err = os.Create(outFilename); err != nil {
     38             log.Fatal(err)
     39         }
     40         defer outFile.Close()
     41     }
     42 
     43     if err = americanise(inFile, outFile); err != nil {
     44         log.Fatal(err)
     45     }
     46 }
     47 
     48 func filenamesFromCommandLine() (inFilename, outFilename string, err error) {
     49     if len(os.Args) > 1 && (os.Args[1] == "-h" || os.Args[1] == "--help") {
     50         err = fmt.Errorf("usage :%s [<] infile.txt [>] outfile.txt",
     51             filepath.Base(os.Args[0]))
     52         return "", "", err
     53     }
     54     if len(os.Args) > 1 {
     55         inFilename = os.Args[1]
     56         if len(os.Args) > 2 {
     57             outFilename = os.Args[2]
     58         }
     59     }
     60     if inFilename != "" && inFilename == outFilename {
     61         log.Fatal("won't overwrite the infile")
     62     }
     63     return inFilename, outFilename, nil
     64 }
     65 
     66 func americanise(inFile io.Reader, outFile io.Writer) (err error) {
     67     reader := bufio.NewReader(inFile)
     68     writer := bufio.NewWriter(outFile)
     69     defer func() {
     70         if err == nil {
     71             err = writer.Flush()
     72         }
     73     }()
     74 
     75     var replacer func(string) string
     76     if replacer, err = makeReplacerFunction(britishAmerican); err != nil {
     77         return err
     78     }
     79     wordRx := regexp.MustCompile("[A-Za-z]+")
     80     eof := false
     81     for !eof {
     82         var line string
     83         line, err = reader.ReadString('
    ')
     84         if err == io.EOF {
     85             err = nil
     86             eof = true
     87         } else if err != nil {
     88             return err
     89         }
     90         line = wordRx.ReplaceAllStringFunc(line, replacer)
     91         if _, err = writer.WriteString(line); err != nil {
     92 
     93             return err
     94         }
     95     }
     96     return nil
     97 }
     98 
     99 func makeReplacerFunction(file string) (func(string) string, error) {
    100     rawBytes, err := ioutil.ReadFile(file)
    101     if err != nil {
    102         return nil, err
    103     }
    104     text := string(rawBytes)
    105     usForBritish := make(map[string]string)
    106     lines := strings.Split(text, "
    ")
    107     for _, line := range lines {
    108         fields := strings.Fields(line)
    109         if len(fields) == 2 {
    110             usForBritish[fields[0]] = fields[1]
    111         }
    112     }
    113 
    114     return func(word string) string {
    115         if usWord, found := usForBritish[word]; found {
    116             return usWord
    117         }
    118         return word
    119     }, nil
    120 }

    这次的格式终于没错

    这个功能里面,我觉得有几个要点,一个是闭包,一个是正则的替换,还有个defer做后事~

    简单理解一下闭包,在构造一个函数的时候,同时让这个函数自带了一些数据等其他内容,比如这里定义这个replacer函数的时候,首先定义replacer的私有数据map,然后返回了使用这个map的函数。这样在调用replacer的时候,就可以使用这个map点数据。(好像说的有点混乱。。)

    正则和defer就没啥好说的了。。

  • 相关阅读:
    应用程序域的用法
    WCF 暴露元数据的配置
    无svc文件发布WCF服务到IIS上
    C#输出毫秒
    [一点一滴学英语]20051017
    从其他平台转向Windows,MS提供了很多便利;那反过来呢?
    Ward Cunningham加入Eclipse?
    [导入][链接]Linux常用命令/快捷键
    [导入][号外]Oracle to buy JBoss, Zend and Sleepycat?
    [导入][链接]Google开始向Linux移植其Windows应用程序?
  • 原文地址:https://www.cnblogs.com/mruoli/p/4695231.html
Copyright © 2020-2023  润新知