1.与C++定义变量方式不同,go语言定义变量引入关键字 var;
var v1 int
var v2 string
var v3 [4]int //数组
var v4 []int //数组切片
var v5 *int //指针
var v6 map[string]int //map,key为string,value为int类型
var v7 func(a int) string //函数 入参为int,返回值string
//也可以一次性定义多个变量,避免重复写关键字 var
var (
v11 int
v12 string
v13 map[int]string
)
以上代码只是声明变量,未赋值的情况下,默认值如下
var v1 int //v1=0
var v2 *int //v2=nil
var v3 string //v3=""
2.变量初始化的几种方式:
//1.先声明,后赋值
var i1 int
i1 = 1
//2.声明同时赋值
var i2 int = 1
//3.声明同时赋值,且可省略变量类型,由编译器自动推导类型
var i3 = 1
var i4="myname"
//4.最简单的定义方式,完全由编译器自动推导类型,但必须是未被声明过的变量,否则报错
i5 := 1
i6 := "your name"
//以下代码将报错
var i7 int
i7 := 1 // no new variables on left side of :=
3.与C/C++相比,go增加了很强大的多重赋值功能
var (
i=1
j=2
)
i,j = j,i //很简单的一句代码就能实现变量i与j的数据互换
4.函数多返回值,类似 LUA 语法,但并不是每个变量都是我们所需要的,所以还增加了匿名变量,是代码看起来更简洁
//假设有以下接口
func GetPersonName()(firstName,lastName,nickName string){
return "Li","Lei","baby"
}
//调用
firstName,lastName,nickName := GetPersonName()
//如果只需要得到nickName
_,_,nickName := GetPersionName()
5.常用的变量类型
//整型
byte
int
uint
uintptr
int8
uint8
int16
uint16
int32
uint32
int64
uint64
//浮点
float32
float64
//复数
complex64
complex128
//字符串
string
//字典
map[key_type]value_type
//通道
chan
//布尔
bool
//字符类型
rune
//指针
*int等
//数组
[array_len]int
//切片slice
[]int
//错误类型
error
//接口
interface
//结构体
struct
6.预定义常量
true,false,iota
//true和false不解释
//iota 比较特殊,在每个const关键字出现时,被重置为0,类似于const中的位置下标值,常被用于枚举
//例
const(
c0 = iota //c0=0
c1 = iota //c1=1
c2 = iota //c2=2
c3 = 1 //虽然没出现iota,但还是会自增
c4 = iota //c4=5
c5 //如果没有赋值表达式,则直接拷贝上一个变量的赋值表达式,c5 = iota,即c5=6
c6 //如果没有赋值表达式,则直接拷贝上一个变量的赋值表达式,c6 = iota,即c6=7
c7 = 1<<iota // 1<<8
c8 // 1<<iota 即 1<<9 更直观体现出‘拷贝’
c9 // 1<<iota 即 1<<10
)
const x = iota //x=0 体现出遇到const则iota被重置为0
const y = iota //y=0 体现出遇到const则iota被重置为0
const(
MSG_ID_0 = iota
MSG_ID_1
MSG_ID_2
MSG_ID_3
MSG_ID_4
MSG_ID_5
)
7.基本运算
常规的运算
+
-
*
/
比较运算
==
>
>=
<
<=
!=
位运算
<<
>>
x^y 异或
x&y 与
x|y 或
^x 取反
8.复数类型
var value1 complex64 = 3 + 12i //3为实部 12为虚部
value2 := complex(3,12) //也可以用内置函数生成复数 value2 = 3 + 12i
r := real(value2) //通过内置函数获取实部 r=3
i := imag(value2) //通过内置函数获取虚部 i=12
9.字符串类型
//基础用法与C++的std::string类似
str := "Hello"
ch := str[0] //可通过下标直接获取第一个字符 ch='H'
//但与C++也有重要区别,字符串初始化之后不能修改字符串中的内容
str[0] = 'w' //这是不允许的,编译报错
//字符串连接
x,y := "hello","world"
z=x+y // z="helloworld"
//字符串长度
len(s)
//字符串遍历的两种方式
str := "helloworld"
n := len(str)
for i:=0;i<n;i++{ //常规的下标访问
ch := str[i]
}
for i,ch:=range str{ //类似迭代器访问
fmt.Println("[",i,"]=",ch)
}
10.函数变量
package main
import "fmt"
func modify(array [10] int){
array[0] = 10
fmt.Println("modify:",array)
}
func main(){
array := [5]int{1,2,3,4,5}
modify(array)
fmt.Println("main:",array)
}
//输出结果
modify:[10,2,3,4,5]
main:[1,2,3,4,5]
//可以从输入内容看出,以上函数入参传递为值传递,并不影响函数外的原变量
11.动态分配内存 - 切片
//简单创建切片的例子
//make([]int,len,cap)
//len是初始化长度,cap是最大容量
package main
import "fmt"
func main(){
mySlice := make([]int,5,10)
fmt.Println("len=",len(mySlice))
fmt.Println("cap=",cap(mySlice))
}
//输出结果
len=5
cap=10
//往切片中追加元素,比如追加3个元素
mySlice=append(mySlice,1,2,3) // 此时mySlice=[0,0,0,0,0,1,2,3]
//也可以追加另一个切片
mySlice2 := []int{7,8,9}
mySlice = append(mySlice,mySlice2...)
//这里必须要有省略号,表示把mySlice2打散,
//相当于mySilce = append(mySlice,7,8,9)
当使用append向切片中追加元素已经超过切片最大容量,则切片会自动扩容分配足够大的内容;
基于切片创建子切片时,遵循左闭右开,切片索引从0开始
slice1 := []int{1,2,3,4,5,6,7,8,9}
slice2 := slice1[0:1] //slice2=[1]
slice3 := slice1[:3] //可省略起始下标,默认从[0:3]开始 slice3=[1,2,3]
slice4 := slice1[2:] //可省略结束下标,默认到[2:len+1] slice4=[3,4,5,6,7,8,9]
slice5 := slice1[:] //可省略起始和结束下标,默认从[0:len+1] slice5=[1,2,3,4,5,6,7,8,9]
//注意!注意!注意!
//修改子切片中的值,会直接影响到原切片的内容
slice3[0]=99
//输出slice1可以得到 [99,2,3,4,5,6,7,8,9]
//所以子切片更类似于对原切片的局部数据块的引用
既然修改子切片内容会直接影响原切片的内容,那么肯定要有完全拷贝的功能,使新切片与原切片完全独立,互不影响
slice1 := []int{1,2,3,4,5}
slice2 := []int{7,8,9}
//使用内置函数,可完成数据的复制
//且按照其中切片最小的元素个数进行复制
copy(slice2,slice1) //复制slice1前3个元素到slice2中 [1,2,3]
copy(slice1,slice2) //复制slice2元素到slice1的前3个位置 [7,8,9,4,5]
12.map集合,以下演示map基础用法,包括声明变量,创建实例,插入元素,查找元素,删除元素
package main
import "fmt"
//声明结构体
type PersonInfo struct{
ID string
Name string
Addr string
}
func main(){
var personDB map[string]PersonInfo //声明map变量,此时变量不可用
personDB = make(map[string]PersonInfo) //使用内置make创建map实例,此时变量可用
//还可以有第二参数指定map的初始长度make(map[string]PersonInfo,100)
personDB["1"] = {"1001","Tom","Room1001"} //插入元素
personDB["2"] = {"1002","Lily","Room1002"}
person,ok := personDB["12"] //ok为查找结果
if ok {
fmt.Println("find")
}else{
fmt.Println("not found")
}
delete(personDB,"1") //删除元素
}