從零開始學GO ---- (1) 變數、常量、基本資料型別

coding丁發表於2020-11-07

從零開始學GO ---- (1) 變數、常量、基本資料型別

第一個GO程式:hello world

程式碼如下:

package main // 宣告 main 包,表明當前是一個可執行程式

import "fmt" // 匯入內建 fmt 包

func main() { // main函式,是程式執行的入口
	fmt.Printf("Hello World!") // 在終端列印 Hello World!
}

然後執行: go build hello.go 進行編譯,之後便可以看到有一個exe檔案,可以直接執行。

一些細節:

  • 宣告main包,表示當前是一個可執行程式
  • 通過import匯入其他包,fmt是標準輸入輸出包,包含有Print函式
  • main函式表示程式入口,並且main函式所在的包名必須是main
  • 函式以func開頭

變數和常量

變數

顯示變數宣告var vatName dateType [= value]

其中,var是關鍵字,用於變數宣告,varName是變數名字,dateType表示資料型別,value是初始值,初始值可以是字面量,也可以是其他變數名或者表示式,不顯示初始化的話將預設為零值。

tips:GO的變數宣告後將立即分配空間

var number int = 1
var name string = "jessy"

//也可以利用型別推導將變數的型別省略
var name, age = "Q1mi", 20

短型別變數宣告varName := value

只能在函式內部短型別宣告,可以使用更簡略的 := 方式宣告並初始化變數 ,GO編譯器將自動型別推斷

//...
func main() {
	n := 10
	m := 200 // 此處宣告區域性變數m
	//...
}

匿名變數:在使用多重賦值時,如果想要忽略某個值,可以使用匿名變數(anonymous variable)。 匿名變數用一個下劃線_表示

func function() (int, string) {
	return 10, "string"
}
func main() {
	x, _ := function()
	_, y := function()
	fmt.Println("x=", x)
	fmt.Println("y=", y)
}

匿名變數不佔用名稱空間,不會分配記憶體,所以匿名變數之間不存在重複宣告。_多用於佔位,表示忽略值

常量

常量使用一個名稱繫結一個記憶體地址,該記憶體地址儲存的資料型別和內容宣告後不可以再變。

//變數前加const就表示常量宣告
const pi = 3.1415
const e = 2.7182

//可以宣告多個變數
const (
    pi = 3.1415
    e = 2.7182
)
//const同時宣告多個常量時,如果省略了值則表示和上面一行的值相同
const (
    n1 = 100
    n2
    n3
)       //則n2 n3都是100

預宣告識別符號iota用在常量宣告中,初始值為0,一組多個變數同時宣告時其值逐行增加,專門用來初始化常量

const (
	c0=iota  //c0==0
	c1=iota  //c1==1
	c2=iota  //c2==2
)
//  <===>  等價於
const(
	c0=iota   //c0==0
    c1        //c1==1
    c2        //c2==2
)
//iota是逐行增加的
const(
	a=1<<iota  // iota==0,so a==1
    b=1<<iota  // iota==1,so b==2
    c=3        //c==3  and iota==3
    d=1<<iota  //iota==3,so d==8
)

基本資料型別

布林型

Go語言中以bool型別進行宣告布林型資料,布林型資料只有truefalse,並且在Go語言中,布林型資料和整型資料不可以相互轉換,如果宣告的布林型不進行初始化,則預設為false

var a bool=true
var b bool=(x>y)&&(x>0)
整型

Go語言內建了12種整數型別, 分別是:int8、int16、int32、int64 對應的有符號整型,和uint8、uint16、uint32、uint64對應的無符號整型,以及byte,int,uint,uintptr。

byte是unit8的別名,int和uint表示整數型別,受特定 CPU 平臺的字長影響。

型別描述
uint8無符號 8位整型 (0 到 255)
uint16無符號 16位整型 (0 到 65535)
uint32無符號 32位整型 (0 到 4294967295)
uint64無符號 64位整型 (0 到 18446744073709551615)
int8有符號 8位整型 (-128 到 127)
int16有符號 16位整型 (-32768 到 32767)
int32有符號 32位整型 (-2147483648 到 2147483647)
int64有符號 64位整型 (-9223372036854775808 到 9223372036854775807)
浮點型

Go語言支援兩種浮點型數:float32float64

使用浮點數要注意,浮點數字會被自動推斷為float64型別,並且使用浮點數不應該使用==或 != 來進行比較,而應該採用一個精度的大小比較去判斷,高精度要求應該採用math標準庫。

var b :=10.00  //會被推斷為float64
var a float32=1.2

列印浮點數時,可以使用fmt包配合%f進行格式化輸出

fmt.Printf("%f\n", math.Pi)  //3.141593
fmt.Printf("%.2f\n", math.Pi) //3.14
複數型別

Go語言內建的複數型別有兩種:complex64complex128,複數在計算機中用兩個浮點數表示,一個表示實部一個表示虛部,complex64的實部和虛部為32位,complex128的實部和虛部為64位。

var value1 complex64=3.2+14i
var value2 =2+10i

Go的複數型別有三個內建函式:complex real imag,分別用於構建複數、返回實部、返回虛部

var v=complex(2.1,3)  //構造複數
a:=real(v)   //a=2.1
b:=imag(v)   //b=3
字串

Go語言將字串作為一種原生的基本資料型別,可以直接使用字串字面量來進行初始化。

  • 字串是常量,可以通過索引訪問,但是不能修改某個位元組的值

    var a ="hello world!"
    b:=a[0]
    a[1]='a'  //錯誤,不可以修改某位元組的值
    
  • 字串尾部不包含NULL字元,與C++不同

  • 採用切片操作時要慎用,因為每轉換一次都需要複製內容(尤其資料量大的時候)

    a:="hello world!"
    b:=[]byte(a)
    
  • 字串的底層實現是一個二後設資料結構,一個是指標指向位元組陣列的起點,另一個是長度

    type stringStruct struct{
    	str unsafe.Pointer //指向底層位元組陣列的指標
        len int            //位元組陣列長度
    }
    
  • 基於字串建立的切片和原字串指向相同的底層字元陣列,一樣不能修改,對字串的切片操作返回的字串仍是string,而非slice

  • string型別常用的一些方法:

    方法介紹
    len(str)求長度
    +拼接字串
    strings.Split分割
    strings.contains判斷是否包含
  • 修改字串:要修改字串,需要先將其轉換成[]rune[]byte,完成後再轉換為string。無論哪種轉換,都會重新分配記憶體,並複製位元組陣列。

    func changeString() {
    	s1 := "big"
    	// 強制型別轉換
    	byteS1 := []byte(s1)
    	byteS1[0] = 'p'
    	fmt.Println(string(byteS1))  //pig
    }
    
  • 字串的切片:

    str := "hello,world"
    fmt.Println(str[6:])  
    //列印結果:world
    
byte和rune型別

Go語言的字元型別有兩種:

  1. uint8型別,或者叫 byte 型,代表了ASCII碼的一個字元。
  2. rune型別,代表一個 UTF-8字元

當需要處理中文、日文或者其他複合字元時,則需要用到rune型別。rune型別實際是一個int32

遍歷一個字串:

	s := "hello,world!"
	for _, r := range s { //rune
		fmt.Printf("%c", r)
	}
	fmt.Println()

相關文章