go学习记录–基础语法

本期将go中的基础语法模块通过代码的方式写了一遍。

上传到了github.后续将不断通过更新项目总结go的学习以及总结。

下面的语法讲解转自golang官网,我简写了代码事例代码

golang官网: https://golang.google.cn/ref/…

golang开源社区: http://tour.studygolang.com/w…

代码地址: https://github.com/A1len/stud…

导读

  • 基础语法
  • 流程控制语句

基础语法

这一部分将对go中的包、函数、申明变量、基本数据类型、常量做一个描述

Go程序是通过将程序包关联在一起而组成。一个包又由一个或多个go源文件组成,这些源文件一起声明了属于该包的常量,类型,变量和函数,并且可以在同一包的所有文件中进行访问。这些元素可以 导出并在另一个包中使用。

import (
  "fmt"
  "math"
)
//1.通过import的方式导入包,可以像java一样多个imprt导入
//也可以通过上述方式  
​
​
​
//2.在导入了一个包之后,就可以用其导出的名称来调用它。
//在 Go 中,首字母大写的名称是被导出的。
//Foo 和 FOO 都是被导出的名称。名称 foo 是不会被导出的。
//执行代码。然后将 math.pi 改名为 math.Pi 再试着执行一下
func main() {
  fmt.Println(math.Pi)
}

函数

函数声明将标识符func绑定到函数。

package main
​
import ("fmt" "unsafe")
​
​
//函数可以返回一个或者多个值,具体看add和multipl函数
//两个或多个连续的函数命名参数是同一类型,可以只需要最后一个参数定义类型
//Go 的返回值可以被命名,并且像变量那样使用。
//返回值的名称应当具有一定的意义,可以作为文档使用
//没有参数的 return 语句返回结果的当前值。也就是`直接`返回
func add(x int, y int)(int){
  return x+y
}
​
func multiple(x , y int)(string ,int){
  return "hello",x
}
​
​
func multiple2(x , y int)(str string ,z int){
  str="hello"
  z=x
  return
}
​
//外部实现,这里其实可以不定义结构体
//后续补充go:linkname
func FlushICache(begin,end int)
​
​
​
func main() {
  x ,y :=multiple(42, 13)
  fmt.Print(x,y)
​
}

申明变量和常量

申明变量可以通过var或者:= 常量使用const

package main
​
import "fmt"
​
​
//go当中声明一个变量可以通过var或者:=
//var可以作用在函数中也可以函数外
//:=只可以在函数中
//go有自动类型推断,如果有初始值,可以不带上变量类型
​
​
var initname="allen"
​
​
var name ,motherland  string
​
var defaultvar string
//常量的定义和变量类似,只是换成了const来申明
const Pi = 3.14
func main()  {
  var num int
  age:=18
​
​
  fmt.Println(defaultvar,num,age)
​
}
​

基本数据类型

package main
​
import (
  "math/cmplx"
  "fmt"
)
​
/*
bool
​
string
​
int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr
​
//一般需要用多大的可以选择多大的数字类型
//如果没有选择将会按照操作系统选择
//比如64位就会走int64
​
​
//go语言中的基础数据类型都有默认值,
//这很正常引用指针得指向一个内存空间,才算初始化了一个变量
//否则一个指针不初始化,很容易造成基础数据类型空指针。。。有点尴尬
​
byte // uint8 的别名
​
rune // int32 的别名,因为unicode是动态的所以选择32位可以完全满足,
    新版本java对于这一块做了自动判断,节省空间
​
​
float32 float64
​
complex64 complex128
 */
var (
  ToBe   bool       = false
  MaxInt uint64     = 1<<64 - 1
  z      complex128 = cmplx.Sqrt(-5 + 12i)
)
​
func main() {
  const f = "%T(%v)\n"
  fmt.Printf(f, ToBe, ToBe)
  fmt.Printf(f, MaxInt, MaxInt)
  fmt.Printf(f, z, z)
}
​

流程控制语句

这部分没有全部列出来只是举了几个典型例子以及常用的说明,具体可以看官网

for

for的用法和java中基本一样,并且go里面是没有while了的

package main
​
import "fmt"
​
​
//for的使用和java中基本是一样的,只是少了一个()
//并且go当中没有while,使用for实现
//java中Doug Lea很喜欢这种写法
func main() {
  sum := 0
  for i := 0; i < 10; i++ {
    sum += i
  }
  fmt.Println(sum)
​
  i := 1
  for i < 1000 {
    i += i
  }
  fmt.Println(i)
​
  for {
    break
  }
}
​

switch

switch的变化比较多,没有条件的 switch 同 switchtrue一样。这一构造使得可以用更清晰的形式来编写长的 if-then-else 链 switch用法比java更方便灵活,不用显示的在语句中加break 如果要实现类似java的一个case成立继续执行后续的case可以使用fallthrough

package main
​
import (
  "fmt"
  "runtime"
  "time"
)
​
​
//switch用法比java更方便灵活,不用显示的在语句中加break
//如果要实现类似java的一个case成立继续执行后续的case可以使用fallthrough
//case也可以直接使用判断语句
​
//以及type switch
​
//todo 后续看一下switch的实现源码
//感觉java的swtich语法糖和go比起来还是较弱,这也是java的历史原因
func main() {
  fmt.Print("Go runs on ")
  switch os := runtime.GOOS; os {
  case "darwin":
    fmt.Println("OS X.")
    //fallthrough 打开注释看看结果
  case "linux":
    fmt.Println("Linux.")
    //fallthrough
  default:
    // freebsd, openbsd,
    // plan9, windows...
    fmt.Printf("%s.", os)
  }
​
​
  t := time.Now()
  switch {
  case t.Hour() < 12:
    fmt.Println("Good morning!")
  case t.Hour() < 17:
    fmt.Println("Good afternoon.")
  default:
    fmt.Println("Good evening.")
  }
​
​
  var a interface{}
​
  a = "abc"
​
​
​
  switch t := a.(type) {
​
  case string:
​
    fmt.Printf("string %s\n", t)
​
  case int:
​
    fmt.Printf("int %d\n", t)
​
  default:
​
    fmt.Printf("unexpected type %T", t)
​
  }
​
}
​

defer

defer 语句会延迟函数的执行直到上层函数返回。延迟调用的参数会立刻生成,但是在上层函数返回前函数都不会被调用 可以理解为先进后出

package main
​
import (
  "fmt"
)
​
//defer的操作其实是一个压栈的方式调用
//先进后出FILO
//可以一次执行下面的三个例子
​
//另外通过例子3其实可以知道defer是有数据拷贝的
//换句话说执行defer的时候数据就保存了一个份
//后续变量怎么改变defer还是输出同样的信息
​
//TODO defer的使用场景后续补充,暂时先当try catch finally使用
​
​
func main() {
  fmt.Println("counting")
​
  a:="hello world"
​
  for i := 0; i < 10; i++ {
    defer fmt.Println(i)
  }
​
  fmt.Println("done")
  //1.os.Exit(0)//直接推出不会执行defer
  //2.return//遇到return才返回
  defer fmt.Println(a)
  //3.a="hello defer"
  fmt.Println("done")//没有return则执行到底
}
​

最后各位可以扫下方二维码关注我公众号,基本每周会推送一到两篇的go学习记录,后续学完基础语法,会准备写一个go微服务项目,源码依然放在github上面。