go 从入门到精通(二)基本数据类型和操作符
一、文件名&關鍵字&標識符
- 所有go源碼都是以.go結尾
- 標識符以字母或下劃線開頭,大小寫敏感
- 下劃線_是特殊標識符,用戶忽略結果
- 保留關鍵字
- 導入包時可以設置別名
下面是保留關鍵字:
二、GO程序的基本結構
package mainimport ("fmt" )func main(){fmt.Println("Hello world") }小練習1
寫一個小程序,對于給定的一個數(shù)字n,求出所有兩兩相加等于n的組合
小練習2
寫一個小程序,包含兩個包,add和main,其中add包中有兩個變量:Name,和age,請問main包中如何訪問Name和age?(用于理解go中大小寫敏感的問題)
main包中的代碼:
package main import ("fmt""go_dev/day02/kexia02/add" )func main() {fmt.Println(add.Name) }add包中的代碼
package add var Name string = "zhaofan" var age int = 23從結果我們可以發(fā)現(xiàn)我們在main包中是不能調(diào)用到add包中的age,但是是可以調(diào)用到Name
這里就是因為大小寫的問題,go中的大寫可以理解為其他語言中的public,小寫理解為private
這里有個問題需要注意:
我們把add包中的代碼改為:
這樣也是錯誤的寫法,go作為編譯型語言,必須通過函數(shù)來進行語句的執(zhí)行,而不能在函數(shù)外執(zhí)行語句
小練習3
開發(fā)一個小程序,使用包別名來訪問包中的函數(shù)或變量
直接對上一個程序的main包進行更改
小練習4
每個源文件都可以包含一個init函數(shù),這個init函數(shù)自動被go運行框架調(diào)用,通過下面例子演示:
運行結果是先打印了init函數(shù)的內(nèi)容,后打印了main函數(shù)中的問題,所以init函數(shù)先與main函數(shù)執(zhí)行
三、函數(shù)的聲明和注釋
函數(shù)聲明
格式為:func 函數(shù)名字(參數(shù)列表)(返回值列表)
例子如下:
func add(){
}
func add(a int,b int) int{
}
func add(a int,b int) (int int){
}
注釋
單行注釋//
多行注釋/* */
四、GO語言的數(shù)據(jù)類型和操作符
常見數(shù)據(jù)類型及分類
GO語言按照類別分為幾下幾種數(shù)據(jù)類型:
布爾型:true或false,例子:var b bool = true
數(shù)字類型:包括整型int和浮點float
字符串類型:這里強調(diào)一下,GO的字符串是由單個字節(jié)連接起來的Go語言的字符串的字節(jié)使用UTF-8編碼標識Unicode文本。
派生類型:這里包括指針類型,數(shù)組類型,結構化類型,Channel類型,函數(shù)類型,接口類型,Map類型
注意:
字符串的時候用雙引號”“,這里也可以用反引號`,通過反引號的方式會保留你的格式,不會對你的內(nèi)容做任何轉(zhuǎn)義
字節(jié)的時候用單引號‘’,同樣也可以通過反引號`
var cc byte = 'c' fmt.println(ccc)
var cc byte =?c?fmt.println(cc)
一個會打印c的ASCII,一個會打印c
關于fmt.Printf()的用法
官網(wǎng)地址:https://go-zh.org/pkg/fmt/
一般
%v 相應值的默認格式。在打印結構體時,“加號”標記(%+v)會添加字段名
%#v 相應值的Go語法表示
%T 相應值的類型的Go語法表示
%% 字面上的百分號,并非值的占位符
布爾
%t 單詞 true 或 false。
整數(shù)
%b 二進制表示
%c 相應Unicode碼點所表示的字符
%d 十進制表示
%o 八進制表示
%q 單引號圍繞的字符字面值,由Go語法安全地轉(zhuǎn)義
%x 十六進制表示,字母形式為小寫 a-f
%X 十六進制表示,字母形式為大寫 A-F
%U Unicode格式:U+1234,等同于 "U+%04X"
浮點數(shù)及其復合構成
%b 無小數(shù)部分的,指數(shù)為二的冪的科學計數(shù)法,與 strconv.FormatFloat
的 'b' 轉(zhuǎn)換格式一致。例如 -123456p-78
%e 科學計數(shù)法,例如 -1234.456e+78
%E 科學計數(shù)法,例如 -1234.456E+78
%f 有小數(shù)點而無指數(shù),例如 123.456
%g 根據(jù)情況選擇 %e 或 %f 以產(chǎn)生更緊湊的(無末尾的0)輸出
%G 根據(jù)情況選擇 %E 或 %f 以產(chǎn)生更緊湊的(無末尾的0)輸出
字符串與字節(jié)切片
%s 字符串或切片的無解譯字節(jié)
%q 雙引號圍繞的字符串,由Go語法安全地轉(zhuǎn)義
%x 十六進制,小寫字母,每字節(jié)兩個字符
%X 十六進制,大寫字母,每字節(jié)兩個字符
指針
%p 十六進制表示,前綴 0x
通過fmt.Printf() 可以格式化輸出到終端,如果想要格式化存儲到變量則是fmt.Sprintf()
數(shù)字類型
數(shù)字類型包括了:
uint8(無符號8位整型,0到255)
uint16(無符號16位整型,0到65535)
uint32(無符號32位整型,0到4294967295)
unint64(無符號64位整型,0到18446744073709551615)
int8(有符號8位整型,-128到127)
int16(有符號16位整型,-32768到32767)
int32(有符號32位整型 ,-2147483648 到 2147483647)
int64(有符號64位整型 ,-9223372036854775808到9223372036854775807)
浮點型
flat32: 32位浮點型數(shù)
flag64: 64位浮點型數(shù)
complex64:32 位實數(shù)和虛數(shù)
complex128:64 位實數(shù)和虛數(shù)
類型轉(zhuǎn)換
舉個例子來理解: var a int = 8 轉(zhuǎn)換為int32 var b int32 = int32(a)
當我們代碼中設計到數(shù)據(jù)計算的時候,要保證兩個數(shù)據(jù)類型完全相同,
var a int 和 var b int32 是不能直接做計算處理的,這個時候就需要用到類型轉(zhuǎn)換
相關操作符
! && || 分別表示非,與,或
== 、=、!=、 <、>、<=、>=
練習1
使用math/rand生成隨機整數(shù),10個小于100的隨機整數(shù)以及10個隨機浮點數(shù)
package mainimport ("fmt""math/rand" )func rand_print(){for i:=0;i<10;i++{fmt.Println(rand.Int31n(100))fmt.Println(rand.Float32())}} func main() {rand_print() }但是這里會造成每次運行程序生成的隨機數(shù)是相同的,解決方式是加入隨機種子:rand.Seed(time.Now().Unix())
五、常量
常用cost修飾,代表永遠是只讀不能修改
const只能修飾boolean,number(int相關類型,浮點類型,complex)和string
語法
const 變量名 [變量類型] = value其中變量類型可以省略
例子
const b string = "hello"
const b int = 23
通常定義常亮的寫法
const (
a = 0
b = 1
)
高級方法
const (
a = iota
b
c
)
這里自動回吧a賦值為0,后面的變量一次加1
六、變量
聲明一個變量的形式是使用var關鍵字格式如下:
var 變量名 變量類型
關于變量的聲明常用的有三種方法:
變量的作用域
在函數(shù)內(nèi)部聲明的變量叫做局部變量,生命周期僅限于函數(shù)內(nèi)部
在函數(shù)外部生命的變量叫做全局變量,生命周期作用域整個包,如果是大寫,作用域整個程序
在函數(shù)內(nèi)的語句塊的內(nèi)的變量只在語句塊,生命周期就是僅限于語句塊內(nèi).這里主要指{} 括起來的語句塊
通過下面的例子理解
例子1
結果會依次打印zhaofan,Jack,zhaofan
這里就是驗證了函數(shù)內(nèi)部的定義的變量,生命周期僅限于函數(shù)內(nèi)部
如果我們把m函數(shù)中的a:="Jack"改為a = "Jack"
結果為:zhaofan,Jack,Jack
例子2
package mainimport ("fmt" ) var a stringfunc f1(){a := "Jack"fmt.Println(a)f2() } func f2(){fmt.Println(a) } func main(){a = "zhaofan"fmt.Println(a)f1() }這個程序的結果會打印zhaofan,Jack,zhaofan
其實這里還是要理解上面的說的關于變量的作用域
值類型和引用類型
值類型:變量直接存儲值,即變量直接指向存在內(nèi)存中的值。內(nèi)存通常在棧中分配
值類型通常包括基本數(shù)據(jù)類型int,float,bool,string以及數(shù)組和struct
var i int = 5
var j int = i
這個時候i和j的值都為5
其實這里內(nèi)存中是將i的值進行了拷貝,我們通過&獲取變量的內(nèi)存地址也可以看出
&i和&j 的內(nèi)存地址是不同的,所以我如果在var j int = i,后繼續(xù)更改i變量的值,并不會影響j的值,因為是不同的內(nèi)存地址存放的值
引用類型:變量存的是一個地址,這個地址存儲最終的值,內(nèi)存通常在堆上分配。通過GC回收
一個引用類型的變量 r1 存儲的是 r1 的值所在的內(nèi)存地址(數(shù)字),或內(nèi)存地址中第一個字所在的位置。
引用類型通常包括指針,slice,map,chan等。
所以如果我們定義了兩個引用類型變量像上面的值類型一樣進行賦值操作則兩者都會改變,因為兩者的引用地址是相同的。
所以在引用類型中變量是拷貝的內(nèi)存地址,而地址最終指向值
小練習1
package mainimport ("fmt" )func main() {var a int = 100var b chan int = make(chan int,1)fmt.Println("a=",a)fmt.Println("b=",b) }結果為:
從這里我們也可以看出值類型和引用類型的區(qū)別
小練習2
寫一個小程序,交換兩個整數(shù)的值
package mainimport ("fmt" )func swap(a int,b int){a,b = b,afmt.Println("a=",a,"b=",b) }func main() {change(5,4) }原文地址:?http://www.cnblogs.com/zhaof/p/7004940.html
總結
以上是生活随笔為你收集整理的go 从入门到精通(二)基本数据类型和操作符的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Go从入门到精通(一)go语言初识
- 下一篇: Go 从入门到精通(三)字符串,时间,流