天天看點

Go語言學習筆記-03變量

作者:閑漁一下

資料類型

1.布爾型,bool

2.無符号整形,uint,uint8,unit16,uint32,uint64

3.有符号整形,int,int8,int16,int32,int64

4.浮點型,float32,float64

5.複數型,complex64,complex128

6.字元串,string,表示Unicode字元序列

7.其他數字類型

byte,uint8的别名,表示單位元組字元

rune,int32的别名,表示一個Unicode碼點

uintptr,大到足夠儲存任何指針類型的整形類型

8.派生類型

數組類型,[n]T,表示元素類型為 T 的 n 個元素的數組的類型

切片類型,[]T,表示元素類型為 T 的可變長度數組的類型

map類型,鍵值對的無序集合,類似于其他語言中的字典或哈希表

結構化類型(struct),由多個字段組成的自定義資料類型

channel類型,用于在goroutine之間進行同步通信

指針類型(Pointer),*T

函數類型,func

接口類型(interface),表示實作特定方法的類型的類型

變量的聲明

go是靜态類型語言,聲明變量時需要确定好變量的資料類型,不能在同一作用域中聲明同名變量

聲明有以下幾種方式

  1. 僅聲明不指派
var 變量名 資料類型
           
  1. 聲明同時指派
var 變量名 資料類型 = 值
           
  1. 聲明時預設變量類型。go編譯器會根據右邊值,自動推導預設類型,若預設類型不是想要的類型,則可以顯式類型轉換
var 變量名 = 值
           
var 變量名 = 值
var 變量名 = 資料類型(值)
           
  1. 同時申明多個變量
var (
變量名1 資料類型1
變量名2 資料類型2
)

var (
變量名1 資料類型1 = 值1
變量名2 資料類型2 = 值2
)
           
  1. 同一行同時聲明多個變量
// 資料類型一緻
var 變量名1, 變量名2 資料類型
var 變量名1, 變量名2 資料類型 = 值1, 值2

// 資料類型不一緻,采用預設資料類型方式
var 變量名1, 變量名2 = 值1, 值2
           
  1. 短變量聲明,相當于聲明一個變量并指派隻能在函數體中使用go編譯器會根據右邊的值,自動推導預設類型,若預設類型不是想要的類型,則可以顯式類型轉換
變量名 := 值
變量名 := 資料類型(值)
變量名1, 變量名2 := 值1, 值2
           

變量的指派

go語言中,類型不同的變量不能指派給對方,如int32的變量,不能直接指派給int的變量

空白辨別符

空白辨別符也稱為匿名占位符,使用_表示

在 Go 語言中, 不允許聲明未使用的變量或導入語句,這時可以使用空白辨別符忽略掉

全局變量

在函數體外聲明的變量是全局變量,也稱為包級變量

隻能使用var方式申明,無法使用短變量聲明方式

package main

// 全局變量
var 變量名 資料類型
var 變量名 = 值
var (
 變量名1 = 值1
 變量名2 = 值2
)

func main() {
}
           

代碼示例

ch03/main.go

package main

// 全局變量聲明
var globalA1 int
var globalB1 = 1

var (
 globalC1 = 1
 globalC2 = 1
)

func main() {
 // 指定變量類型,沒有初始化
 var a1 int

 // 聲明并初始化
 var b1 int = 1

 // 變量聲明塊,批量聲明多個變量
 var (
  c1 int    = 128
  c2 int8   = 6
  c3 string = "hello"
  c4 rune   = 'A'
  c5 bool   = true
 )

 // 在一行同時聲明多個變量
 var d1, d2, d3 int = 1, 2, 3

 // 在一行同時聲明多個變量,類型不一緻
 var (
  e1, e2, e3 = "e1", 2, 3.0
 )

 // 省略類型資訊的聲明,類型為預設類型
 var f1 = 1          // int
 var f1_1 = int32(1) // int32
 var f2 = 1.1        // float64
 var f3 = 'c'        // int32
 var f4 = "d"        // string
 var f5 = true       // bool

 // 短變量聲明,申明并指派,隻能在函數體中使用
 // 相當于
 // var a int
 // a = 12
 g1 := 12
 g2 := 'A'
 g3 := "hello"
 g4, g5, g6 := 12, 'A', "hello"

 // 使用空白辨別符_忽略掉未使用的變量
 _ = globalA1
 _ = globalB1
 _, _ = globalC1, globalC2
 _ = a1
 _ = b1
 _, _, _, _, _ = c1, c2, c3, c4, c5
 _, _, _ = d1, d2, d3
 _, _, _ = e1, e2, e3
 _, _, _, _, _, _ = f1, f1_1, f2, f3, f4, f5
 _, _, _, _, _, _ = g1, g2, g3, g4, g5, g6

 // 當有新變量申明時,需要使用短變量聲明方式
 _, h7 := 0, 0
 _ = h7
}
           

fmt包

fmt包主要用于向外輸出内容和擷取輸入内容

Println

列印多個值并換行

ch03/fmt/main.go

package main

// 導入fmt包的包路徑
import "fmt"

func main() {
 fmt.Println(1, 2, 3)
 fmt.Println(4, 5, 6)
}
           

上述代碼輸出

1,2,3
4,5,6
           

Printf

格式化輸出,通過不同的占位符控制輸出格式

常用占位符

占位符說明%v值的預設格式表示%+v類似%v,但輸出結構體時會添加字段名%#v值的Go文法表示%T列印值的類型%%百分号%d列印整數%c列印對應unicode碼值%s列印字元串或[]byte%f列印浮點數%t列印布爾類型

ch03/fmt/main.go

package main

import "fmt"

func main() {
 var a1 = 1
 var a2 = 'a'
 var a3 = true
 fmt.Printf("%d %c %t", a1, a2, a3)
}

           

上述代碼輸出

1 a true
           

預設類型

預設指定類型時,go會根據右值自動推導其資料類型

值類型備注整數int當數值不在int所能表示的範圍内,則需要顯式指定資料類型浮點數float64

字元runeint32的别名,與int32等價字元串string

true,falsebool

ch03/defaulttype/main.go

package main

import "fmt"

func main() {
 var a = 1
 var b = 1.1
 var c = 'a'
 var d = "abc"
 var e = true

 fmt.Printf("變量a的類型為%T\n", a)
 fmt.Printf("變量b的類型為%T\n", b)
 fmt.Printf("變量c的類型為%T\n", c)
 fmt.Printf("變量d的類型為%T\n", d)
 fmt.Printf("變量e的類型為%T\n", e)
}
           

上述代碼輸出

變量a的類型為int
變量b的類型為float64
變量c的類型為int32  
變量d的類型為string 
變量e的類型為bool
           

零值

當隻聲明不指派時,不同資料類型的變量會賦予其對應的零值

零值使得變量可以開箱即用,無需顯示初始化,即零值可用

内置原生類型預設值零值是否可用所有整形類型0是浮點類型0.0是布爾類型false是字元串類型""是指針、接口、切片、channel、map和函數類型nil否struct各字段對應類型的零值看具體字段的類型數組填充對應類型的零值是

例子

ch03/zerovalue/main.go

package main

import "fmt"

func main() {
 var var1 int
 var var2 float32
 var var3 bool
 var var4 string
 var var5 byte
 var var6 [5]int
 var var7 chan int
 var var8 map[string]int
 var var9 []int
 var var10 func() int

 // 注意有些是用%v,有些是用%#v

 fmt.Printf("int的零值為%v\n", var1)
 fmt.Printf("float32的零值為%v\n", var2)
 fmt.Printf("bool的零值為%v\n", var3)
 fmt.Printf("string的零值為%#v\n", var4)
 fmt.Printf("byte的零值為%v\n", var5)
 fmt.Printf("[5]int的零值為%v\n", var6)

 fmt.Printf("[]int的零值為%#v\n", var9)
 fmt.Printf("chan int的零值為%#v\n", var7)
 fmt.Printf("map的零值為%#v\n", var8)
 fmt.Printf("func() int的零值為%#v\n", var10)
}
           

上述代碼輸出

int的零值為0
float32的零值為0                   
bool的零值為false                  
string的零值為""                   
byte的零值為0                      
[5]int的零值為[0 0 0 0 0]          
[]int的零值為[]int(nil)            
chan int的零值為(chan int)(nil)    
map的零值為map[string]int(nil)     
func() int的零值為(func() int)(nil)
           

可以看出預設值為nil的資料類型類型不是單純的nil,而是帶有具體資料類型的nil,它們是不等價的

作用域

在go語言中,{}包括的内容稱之為一個代碼塊,可以嵌套,外層代碼塊的作用域包括所有内層代碼塊,換言之,外層代碼塊的變量可以在内層代碼塊内使用,在内層代碼塊定義與外層代碼塊同名的變量,會遮蔽外層代碼塊的同名變量,這種現象稱之為變量遮蔽

除了有顯示代碼塊,還有隐式代碼塊,包括if,for,switch

例子

ch03/variablemasking/main.go

package main

import "fmt"

var a = 1

func main() {
 {
  // 遮蔽包級變量a
  a := 2
  fmt.Println(a) // 2
 }

 if a := 3; a == 3 {
  fmt.Println(a) // 3
 }

 // 等價于上面的if語句,外層的{}就是隐藏的代碼塊
 {
  a := 3
  if a == 3 {
   fmt.Println(a) // 3
  }
 }

 // 都不影響包級變量a
 fmt.Println(a) // 1
}

           

筆記位址

github:https://github.com/xianyuyixia/gotrip

繼續閱讀