Go语言基础学习二-简单的代码分析
2017-03-20 18:00
676 查看
Go语言基础学习二
一点经验:
main()函数作为整个程序的入口,没有参数,也没有返回值,还有一个函数init()先于main()执行,以后待讲。
导入包中fmt提供格式化文本和读入格式文本的函数,os包提供了跨平台的操作系统层面变量及函数,包括保存命令行参数的类型os.Args
strings包提供处理字符串的函数。
go程序中不含有分号,分号由编译器自动添加。
filepath.Base()函数会返回传入路径的基础名,Go语言采用单引号表达字符,Go语言具有强类型转换,将int16与int32不能直接相加,需要进行类型转换。
栈-自定义类型及其方法,自定义栈可以通过空接口来实现将异构(类型不同的)的元素混合存储,因为go语言的所有类型都实现了空接口。
func (stack *Stack) Top() (interface{},error){
return stack[len(stack)-1],nil
} 函数的声明,第一个圆括号 stack *Stack表示一个类型为指向Stack的参数,名为stack,最后一个圆括号表示返回的值,返回两个值,一个是空接口,一个是错误信息。
切片(在我的理解,就是数组),切片的内容可以通过索引来表示[first:end]一定范围的值。
buffo包提供了带缓冲的I/O处理能力,io包提供了底层I/O能力,包含有io.Reader及io.Writer接口,io/ioutil包提供了一系列高级文件处理函数。regexp包则提供了强大的正则表达式支持。
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strings"
)
var britishAmerican = "british-american.txt"
func init() {/*进入函数main()之前,首先要执行init()内部的内容,获取当前目录并构建单词转化所需的文本路径*/
dir, _ := filepath.Split(os.Args[0])
britishAmerican = filepath.Join(dir, britishAmerican)
}
func main() {
inFilename, outFilename, err := filenamesFromCommandLine()
/*调用filenamesFromCommandLine()函数获取命令行中的数据输入文件和输出文件,返回值为输入文件名和输出文件名及错误信息*/
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是指推迟执行,直到main()函数正常返回会调用该执行语句,关闭文件,回收内存,当程序崩溃时,不会执行,但是go语言系统会自动关闭所有打开的文件,垃圾回收器会回收内存*/
defer inFile.Close()
}
if outFilename != "" {
/*os.Create()读取一个文件,若文件不存在创建该文件,若存在,将该文件长度截为0*/
if outFile, err = os.Create(outFilename); err != nil {
log.Fatal(err)
}
defer outFile.Close()
}
/*americanise该函数用于替换英式单词为美式单词*/
if err = americanise(inFile, outFile); err != nil {
log.Fatal(err)
}
}
/*该函数用于分析命令行*/
func filenamesFromCommandLine() (inFilename, outFilename string,
err error) {
/*os.Args保存有命令行参数,命令行参数大于1,且可以分析-h及--help等参数为命令解释请求*/
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) {
/*向bufio.NewReader传入实现io.Rreader接口的值,提供缓冲机制*/
reader := bufio.NewReader(inFile)
writer := bufio.NewWriter(outFile)
/*延迟至main()函数返回,刷新写缓冲区,确保全部写入*/
defer func() {
if err == nil {
err = writer.Flush()
}
}()
/*定义一个替换器函数,参数为string,返回string*/
var replacer func(string) string
/*makeReplacerFunction根据单词替换文本britishAmerican生成替换器replacer*/
if replacer, err = makeReplacerFunction(britishAmerican); 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 // io.EOF isn't really an error
eof = true // this will end the loop at the next iteration
} else if err != nil {
return err // finish immediately for real errors
}
/*对读取的每一行进行替换器替换并写入输出文件*/
line = wordRx.ReplaceAllStringFunc(line, replacer)
/*这里的_表示空标记符,作为一个占位符放在一个需要变量的地方,并忽略掉该变量的值。*/
if _, err = writer.WriteString(line); err != nil {
return err
}
}
return nil
}
/*根据单词替换文本生成替换器replacer*/
func makeReplacerFunction(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 {
/*每一行将根据空格符生成对应切片,strings.Fields这个函数就是以空白分割符来分隔字符串*/
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
}
go语言中字符串类型的内部表示统一为utf-8编码的。
go语言中的映射,切片和通道都是要通过make()函数来创建的。
for。。range语法用于遍历切片和数组非常方便,每次迭代它会返回切片的索引和在该切片上的元素值。
一点经验:
main()函数作为整个程序的入口,没有参数,也没有返回值,还有一个函数init()先于main()执行,以后待讲。
导入包中fmt提供格式化文本和读入格式文本的函数,os包提供了跨平台的操作系统层面变量及函数,包括保存命令行参数的类型os.Args
strings包提供处理字符串的函数。
go程序中不含有分号,分号由编译器自动添加。
filepath.Base()函数会返回传入路径的基础名,Go语言采用单引号表达字符,Go语言具有强类型转换,将int16与int32不能直接相加,需要进行类型转换。
栈-自定义类型及其方法,自定义栈可以通过空接口来实现将异构(类型不同的)的元素混合存储,因为go语言的所有类型都实现了空接口。
func (stack *Stack) Top() (interface{},error){
return stack[len(stack)-1],nil
} 函数的声明,第一个圆括号 stack *Stack表示一个类型为指向Stack的参数,名为stack,最后一个圆括号表示返回的值,返回两个值,一个是空接口,一个是错误信息。
切片(在我的理解,就是数组),切片的内容可以通过索引来表示[first:end]一定范围的值。
buffo包提供了带缓冲的I/O处理能力,io包提供了底层I/O能力,包含有io.Reader及io.Writer接口,io/ioutil包提供了一系列高级文件处理函数。regexp包则提供了强大的正则表达式支持。
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strings"
)
var britishAmerican = "british-american.txt"
func init() {/*进入函数main()之前,首先要执行init()内部的内容,获取当前目录并构建单词转化所需的文本路径*/
dir, _ := filepath.Split(os.Args[0])
britishAmerican = filepath.Join(dir, britishAmerican)
}
func main() {
inFilename, outFilename, err := filenamesFromCommandLine()
/*调用filenamesFromCommandLine()函数获取命令行中的数据输入文件和输出文件,返回值为输入文件名和输出文件名及错误信息*/
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是指推迟执行,直到main()函数正常返回会调用该执行语句,关闭文件,回收内存,当程序崩溃时,不会执行,但是go语言系统会自动关闭所有打开的文件,垃圾回收器会回收内存*/
defer inFile.Close()
}
if outFilename != "" {
/*os.Create()读取一个文件,若文件不存在创建该文件,若存在,将该文件长度截为0*/
if outFile, err = os.Create(outFilename); err != nil {
log.Fatal(err)
}
defer outFile.Close()
}
/*americanise该函数用于替换英式单词为美式单词*/
if err = americanise(inFile, outFile); err != nil {
log.Fatal(err)
}
}
/*该函数用于分析命令行*/
func filenamesFromCommandLine() (inFilename, outFilename string,
err error) {
/*os.Args保存有命令行参数,命令行参数大于1,且可以分析-h及--help等参数为命令解释请求*/
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) {
/*向bufio.NewReader传入实现io.Rreader接口的值,提供缓冲机制*/
reader := bufio.NewReader(inFile)
writer := bufio.NewWriter(outFile)
/*延迟至main()函数返回,刷新写缓冲区,确保全部写入*/
defer func() {
if err == nil {
err = writer.Flush()
}
}()
/*定义一个替换器函数,参数为string,返回string*/
var replacer func(string) string
/*makeReplacerFunction根据单词替换文本britishAmerican生成替换器replacer*/
if replacer, err = makeReplacerFunction(britishAmerican); 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 // io.EOF isn't really an error
eof = true // this will end the loop at the next iteration
} else if err != nil {
return err // finish immediately for real errors
}
/*对读取的每一行进行替换器替换并写入输出文件*/
line = wordRx.ReplaceAllStringFunc(line, replacer)
/*这里的_表示空标记符,作为一个占位符放在一个需要变量的地方,并忽略掉该变量的值。*/
if _, err = writer.WriteString(line); err != nil {
return err
}
}
return nil
}
/*根据单词替换文本生成替换器replacer*/
func makeReplacerFunction(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 {
/*每一行将根据空格符生成对应切片,strings.Fields这个函数就是以空白分割符来分隔字符串*/
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
}
go语言中字符串类型的内部表示统一为utf-8编码的。
go语言中的映射,切片和通道都是要通过make()函数来创建的。
for。。range语法用于遍历切片和数组非常方便,每次迭代它会返回切片的索引和在该切片上的元素值。
相关文章推荐
- Go语言基础学习三-简单的代码分析(并发)
- Go语言基础学习五-一些数值操作的简单例子
- phpwind代码分析之global.php简单说明(主要学习php基础知识的应用)
- 基础学习笔记之opencv(21):一个简单有趣的皮肤检测代码
- GO语言基础学习
- 黑马程序员——零基础学习iOS开发——03 c语言基础语法:关键字、标示符、注释、数据结构、变量、变量内存分析、scanf函数
- GO1.6语言学习笔记2-安装配置及代码组织
- Linux内核分析第二周学习博客——完成一个简单的时间片轮转多道程序内核代码
- 关于Python数据分析基础教程 Numpy学习指南 第二版 第三章中代码所呈现的问题
- 代码函数从零开始学习OpenCL开发(二)一个最简单的示例与简单性能分析
- 例题:计算运费。c#语言基础,比较简单。看代码输入格式和方法。同样方法可以做一个 出租车打车的程序
- go语言日志记录库简单使用方法实例分析
- Go语言学习三:Go基础(iota,array,slice,map,make,new)
- 黑马程序员---objective-c基础学习--第一个oc程序及代码分析
- Go语言_基础学习篇
- STL基础学习(STL中的容器解析、代码展示、例题分析,帮助你学STL)
- GO语言学习——简单的key-valeu数据库的实现
- go语言 新手学习笔记 go基础教程
- Java学习笔记之语言基础――Java代码安全的概念
- C语言学习基础代码记录