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

 

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