基本语法

Go 是一门静态语言。

基本类型

Go 的 基本类型有

布尔类型:bool

字符串:string

// 后面的数字代表该类型占多少位
// uint 和 int 占多少位取决于 CPU ,如果是32位CPU就是4个字节(32位),如果是64位就是8个字节(64位)

有符号整形:int  int8  int16  int32  int64

无符号整形:uint uint8 uint16 uint32 uint64 uintptr

                  byte // uint8 的别名

                  rune // int32 的别名, 代表一个Unicode码点

浮点数:float32 float64

复数:complex64 complex128
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

什么是string

参考文档Go系列 string、bytes、rune的区别open in new window -- Randal

go语言有以下两种表示字符串的方法:

  • 双引号,如:“gogogo\n”,使用转义字符

  • 反引号,如:gogogo\n,不使用转义字符,字符串的内容将和赋值保持严格一致

Go语言中,string就是只读的采用utf8编码的字节切片(slice) 因此用len函数获取到的长度并不是字符个数,而是字节个数。 for循环遍历输出的也是各个字节。

因此如果以string[i] 只拿到一个字节,对于多字节表示的文字来说就会出现乱码。

rune

rune是int32的别名,代表字符的Unicode编码,采用4个字节存储。

对于上述问题,可以将string转成rune,这意味着任何一个字符都用4个字节来存储其unicode值,这样每次 遍历rune[i] 取值的时候返回的就是unicode值,而不再是字节了,这样就可以解决乱码问题了。

s := "汉字"
for _, v := range s {
//使用 range 遍历。这时 v 就是 rune 类型,自然就不会出现乱码问题
        fmt.Printf("%c", v)

    }
1
2
3
4
5
6

声明&赋值&类型推导

作用域

参考GoLang 变量作用域open in new window --luxixing

在 Golang 中,变量作用域分为:

  • 本地局部变量

  • 全局变量

  • 参数变量

本地局部变量

定义:在函数或者在语义块(if/for等)中定义的变量

生效范围:定义在函数里面则在整个函数范围有效; 定义在语义块,则在整个语义块生效

全局变量

定义:函数外部定义的变量都属于全局变量;全局变量声明必须以 var 开头

生效范围:当前 package 内,如果想要其他 package 访问,全局变量以大写开头

参数变量

定义:函数调用时传递的变量

生效范围:函数范围(但是有可能会可变传入参数的值,取决于传递的参数的类型)

变量

Go 使用 var 声明变量,变量类型放置在变量名后面。 变量在定义时没有明确的初始化时会赋值为零值

零值: 数值类型为 0, 布尔类型为 false, 字符串为 ""(空字符串)。 零值为nil(即null):

  • 指针

  • 切片

  • map

  • chan

  • error

  • func

var a int          
var b = 5  // 声明+复制

b++ //Go 中只有 b++,没有 ++b

//多变量声明
var i,j,k int  
var i,j,k int =1,2,3  //多变量声明+赋值,=号后依次赋值
or
var (
      d int
      e float32
        )
        
var (
      d int=2
      e float32=12345.5
        )
        

//类型推导
a := 5  //Go 会根据赋值推导出该变量的类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

:= 无法用于声明全局变量

类型转换

Go 里没有隐式转换,只有显式转换

表达式 T(v) 将值 v 转换为类型 `T`

一些关于数值的转换:

var i int = 42
var f float64 = float64(i)
var u uint = uint(f)
或者,更加简单的形式:

i := 42
f := float64(i)
u := uint(f)
1
2
3
4
5
6
7
8
9
10
11
12

常量

Go 使用 const 声明常量,变量类型放置在变量名后面

const a int = 10
  //a=20       //常量不允许修改。会报编译错误:cannot assign to a

const b = 20.345  // 不写类型,也能自动判断出类型,注意:常量声明赋值 无需用:= ,只用等于号即可。

const (
    c=2
    d=3.5    //常量 d 没有使用,没报错
)
1
2
3
4
5
6
7
8
9

访问权限

在 Go 里这被称为可导出性。 除了内置类型外,区别就在于类型名称的首字母是否大写

  • 大写 -- 可导出性

  • 小写 -- 不可导出性

分支

ifswitch

if

//if只支持一个初始化语句,初始化语句与判断语句以;分割。 初始化语句也可以拿出来单独赋值。

  if s := "马"; s == "马云" {
    fmt.Printf("阿里巴巴\n")
  }else if s == "马化腾" {
        s ="云"
    fmt.Printf("腾讯\n")
  }else{
    fmt.Printf("xxx\n")
  }
1
2
3
4
5
6
7
8
9
10

switch

switch time.Saturday {
  case today + 0:
    fmt.Println("Today.")
  case today + 1:
        fmt.Println("Tomorrow.")
        fallthrough
  case today + 2:
    fmt.Println("In two days.")
  default:
    fmt.Println("Too far away.")
  }
1
2
3
4
5
6
7
8
9
10
11

fallthrough: 当 case today + 1 后,不管下面的分支是否 case ,都会执行分支内的语句

没有条件的 switch:

这一构造使得可以用更清晰的形式来编写长的 if-then-else 链。

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.")
  }

1
2
3
4
5
6
7
8
9
10

循环

Go 里没有 whiledo while ,只有 for。 虽然没有 while ,但是 for 集成了 while 作用。

用法一

sum := 0
  for i := 0; i < 10; i++ {
    sum += i
  }
1
2
3
4

用法二

死循环

//不写条件 就是 死循环 
  for {
  }
1
2
3

用法三

sum := 1
  for ; sum < 1000; {
    sum += sum
  }
  fmt.Println(sum)
}
1
2
3
4
5
6

用法四

while 一样

sum := 1
  for sum < 1000 {
    sum += sum
    }
1
2
3
4

函数

函数使用 func 定义 ,可以没有参数或接受多个参数,可以没有返回值或返回多个返回值。 返回值可声明变量,在函数内使用。 参数类型和返回值类型在变量名之后

//参数
func add(x int, y int) int {
  return x + y
}

func add(x, y int) int {
  return x + y
}
//无返回值
func add(x, y int) {
  //dosomthing
}
//返回值
func add(x, y int) int {
  return x + y
}

func add(x, y int) (a int) {
    a = 10//函数内使用
  return x + y+a
}

func add(x, y int) (int,int) {
  return x + y,1
}
func add(x, y int) (a int,b int) {
  return x + y,1
}

// return == return a,b
func add(x, y int) (a int,b int) {
    a = x+y
    b = 1
  return 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

import

导包

//单个包
import "fmt"

//多个包
import "fmt"
import "math/rand"
or
import (
  "fmt"
  "math/rand"
)
1
2
3
4
5
6
7
8
9
10
11
Last Updated: