golang的初认识以及实践

这篇博客也算当做我这几点学习go语言的一个小总结和小复习吧

golang的简单介绍

Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。
Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,

并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。
golang

golang的特点


  1. 简洁、快速、安全
  2. 并行、有趣、开源
  3. 内存管理、v数组安全、编译迅速

简单说一下我对着门语言的认识,因为我仅仅是刚刚了解这门语言,还有很多地方要继续了解,就目前的掌握的来说,go跟python在语法上有那么一点点的相似,但是go又跟python不同,它不是面向对象的。
在他的内存管理这方面,它又跟c语言这类比较早期的高级语言有些相似,可以说,go语言是综合了python和c语言这些的优点而创的。
比如,在数组这方面,go可以直接通过index而获取子数组,比如a[1:3],跟python相似,相对于c语言来说,操作方面就简单了很多,对于程序员来讲是相当友好了

go练习

废话不对说了,先从各方面总结一下我学习的心得吧

1.首先,最基本的就是语法规则了,这个就跟我们学语言一样,要想会用,就先要懂语法,这是最基础的东西。
那么go的语法有什么要注意的地方呢
①变量,这里go语言的变量声明的时候可以不用声明类型,初始化的时候会根据变量的类型自己决定
②函数,函数格式要注意go语言的函数是将返回值的类型放到参数列表后面
③声明跟使用,这里要注意的一点是 := 符号,这个符号是包含了声明和初始化两个作用,但是这个符号只能用于声明局部变量,要想声明全局变量,就一定要用var
④关于切片slice,这里在使用的过程中,对于起始和结束下标,起始下标多对应的元素是包含在结果中的,而结束下标是不算的,也就是说
对于s :=[] int {1,2,3,4,5 } s[1:3] 是等于{2, 3}而不是{2, 3, 4},这也是我遇到的一个问题
2.获取程序命令行参数
可以直接通过os.Args来获取,这一点跟c语言的main(argc, argc)是一样的功能,但是操作起来就简单一些了
3.输出,通过fmt一些内置的函数来实现
Printf跟c语言的printf基本一样,实现方法也是类似的
Println不是格式化输出,而是输出一整行
另外我们有的时候可能需要的并不是将格式化的字符串输出而是将他们保存到另一个字符串中,那么,这个时候,我们就会用到fmt.Sprintf()这个函数跟printf用法一样,不同的是这个函数并不是将格式化的字符串打印到stdout中,而是作为返回值,比如
str:= fmt.Sprintf(“Can not open file:%s”, sstr)这样就把格式化的字符串保存到str中了
4.文件的操作
文件的操作对应的有文件的打开,关闭,读和写这几个
打开 os.OpenFile(name, flag, perm),第一个参数是要打开的文件的文件名,是一个字符串,包括文件的路径(相对路径,绝对路径),第二个参数包括几个选项:
O_RDONLY:只读模式(read-only)
O_WRONLY:只写模式(write-only)
O_RDWR:读写模式(read-write)
O_APPEND:追加模式(append)
O_CREATE:文件不存在就创建(create a new file if none exists.)
O_EXCL:与 O_CREATE 一起用,构成一个新建文件的功能,它要求文件必须不存在(used with O_CREATE, file must not exist)
O_SYNC:同步方式打开,即不使用缓存,直接写入硬盘
O_TRUNC:打开并清空文件
如果用到了多个标记,那么不同的标记之间用|操作隔开,比如
outputFile, err = os.OpenFile(a, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0)
最后一个以为为0
关闭 对应的操作为defer f.Close(),这个函数并不是立刻关闭函数,而是在调用结束,函数返回的时候一次关闭,调用这个函数只是把这个调用放入一个等待堆栈中,等待函数返回值,再一次调用这些函数,所以一般可以在打开一个文件之后,就调用这个函数,以免后面忘记关闭
读写,一般可以通过使用缓冲区来方面读写操作
比如rd := bufio.NewReader(inputFile),这样就打开了一个读文件的缓冲区,那么读文件就可以直接从缓冲区读,比如读取一行line, err := rd.ReadString(‘\n’)

程序代码:

package main
import (
  "fmt"
  "os"
  "bufio"
  "io"
  "log"
  "strconv"
  //"io/ioutil"
)
func self_logger(myerr interface{}) {
    logfile, err := os.OpenFile("./ErrorLog", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0)
    if err != nil {
        fmt.Printf("%s\r\n", err.Error())
        os.Exit(-1)
    }
    defer logfile.Close()
    logger := log.New(logfile, "\r\n", log.Ldate|log.Ltime|log.Llongfile)
    logger.Println(myerr)
}
func printUsage() {
  fmt.Printf("Usage: ./selpg -s开始页号 -e结束页号 [ -l每页行号 | -f | 输入文件名]\n")
}
func main()  {
  defer func() { // 必须要先声明defer,否则不能捕获到panic异常
        if err := recover(); err != nil {
            self_logger(err) // 这里的err其实就是panic传入的内容,55
        }
    }()

  var b = os.Args
  //length := len(b)
  var lnum int = 12//default line number
  var err error
  var inputFile *os.File = os.Stdin
  var outputFile *os.File = os.Stdout
  var infile, outfile bool = false, false
  var flag bool = false
  var snum int = -1
  var enum int = -1
  for i, a := range b[1:] {
    if a[0:2] == "-s" {
      snum,err = strconv.Atoi(a[2:])
      if (err != nil) {
        printUsage()
        panic(err)
      }
    } else if a[0:2] == "-e" {
      enum, err = strconv.Atoi(a[2:])
      if (err!= nil) {
        printUsage()
        panic(err)
      }
    } else if a[0:2] == "-l" {
      lnum, err = strconv.Atoi(a[2:])
      if (err!= nil) {
        printUsage()
        panic(err)
      }
    } else if a == "-f" {
      flag = true
    } else if infile == false {
      inputFile, err = os.OpenFile(a, os.O_RDONLY, 0)
      if err != nil {
        errstr:= fmt.Sprintf("Can not open file:%s", a)
        printUsage()
        panic(errstr)
      }
      infile = true
      defer inputFile.Close()
    } else if outfile == false {
      os.OpenFile(name, flag, perm)
      outputFile, err = os.OpenFile(a, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0)
      if err != nil {
        errstr:= fmt.Sprintf("Can not open file:%s", a)
        printUsage()
        panic(errstr)
      }
      outfile = true
      defer outputFile.Close()
    } else {
      fmt.Printf("Undefined option [%s]\n", a)
      errstr := fmt.Sprintf("Undefined option [%s]", a)
      printUsage()
      panic(errstr)
    }
    i++
  }
  if snum < 0||enum < 0 {
    printUsage()
    os.Exit(-1)
  }
  if (snum > enum) {
    errstr := fmt.Sprintf("start num(%d) is gratter than end number(%d)", snum, enum)
    panic(errstr)
  }
  if flag {
    lnum = 1
  }
  rd := bufio.NewReader(inputFile)
  wt := bufio.NewWriter(outputFile)
  var lc int = 0
  var pc int = 0
  for true {
      line, err := rd.ReadString('\n') //以'\n'为结束符读入一行
      if err != nil || io.EOF == err {
          break
      }
      lc++
      if lc == lnum {
        lc = 0;
        pc++
      }
      if pc >= snum&&pc<=enum {
        _, err := wt.WriteString(line)
        if err != nil {
          panic(err)
        }
        wt.Flush()
      } else if pc > enum {
        break
      }
  }
  if pc < snum {
    errstr := fmt.Sprintf("start number (and end number) is grater than the whole pages in the file")
    panic(errstr)
  }
  if pc < enum {
    errstr := fmt.Sprintf("end number is grater than the whole pages in the file")
    panic(errstr)
  }
}

这个程序的功能就是基本上实现命令行传输参数,类似于我们常用的
gcc -o -c -Wall 这类的参数
github地址:https://github.com/Catiks/selpg

相关文章
相关标签/搜索