Go学习笔记-基本语法

261 阅读5分钟

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

什么是string

参考文档Go系列 string、bytes、rune的区别 -- 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)

    }

声明&赋值&类型推导

作用域

参考GoLang 变量作用域 --luxixing

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

  • 本地局部变量
  • 全局变量
  • 参数变量

本地局部变量

定义:在函数或者在语义块(if/for等)中定义的变量 生效范围:定义在函数里面则在整个函数范围有效; 定义在语义块,则在整个语义块生效

全局变量

定义:函数外部定义的变量都属于全局变量;全局变量声明必须以 var 开头 生效范围:当前 package 内,如果想要其他 package 访问,全局变量以大写开头

参数变量

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

变量

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

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

  • 指针
  • 切片
  • map
  • chan
  • error
  • func
var a int					
var b = 5  // 声明+复制

//多变量声明
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 会根据赋值推导出该变量的类型

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

类型转换

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)

常量

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

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

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

const (
    c=2
    d=3.5		//常量 d 没有使用,没报错
)

访问权限

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

  • 大写 -- 可导出性
  • 小写 -- 不可导出性

分支

ifswitch

if

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

	if s := "马"; s == "马云" {
		fmt.Printf("阿里巴巴\n")
	}else if s == "马化腾" {
        s ="云"
		fmt.Printf("腾讯\n")
	}else{
		fmt.Printf("xxx\n")
	}

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

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

没有条件的 switch:

没有条件的 switch 同 switch true 一样。

这一构造使得可以用更清晰的形式来编写长的 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.")
	}

循环

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

用法一

sum := 0
	for i := 0; i < 10; i++ {
		sum += i
	}

用法二

死循环

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

用法三

sum := 1
	for ; sum < 1000; {
		sum += sum
	}
	fmt.Println(sum)
}

用法四

while 一样

sum := 1
	for sum < 1000 {
		sum += sum
    }

函数

函数使用 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 
}

import

导包

//单个包
import "fmt"

//多个包
import "fmt"
import "math/rand"
or
import (
	"fmt"
	"math/rand"
)