go变量及运算

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")        //删除元素
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章