const
var
type
幾個(gè)關(guān)鍵詞的簡(jiǎn)單使用
package main
import "fmt"
// 定義常量
const (
P = 3.14
const1 = 1
const2 = "2"
const3 = 3
)
//全局變量的聲明與賦值
var (
name = "james"
age = 18
name2 = "nihao"
)
// 一般類(lèi)型的聲明 type關(guān)鍵字
type (
newType int
type1 float32
type2 string
)
func main() {
fmt.Printf("Hello %s!\n", name) // Hello james!
}
重點(diǎn)理解第三個(gè)type關(guān)鍵詞,已知這些類(lèi)型雇逞,int荤懂,string等等,但是type可以聲明自己的類(lèi)型塘砸,這里newType屬于一個(gè)新的類(lèi)型节仿,但是他的基礎(chǔ)類(lèi)型還是int,但跟int并不是同一個(gè)類(lèi)型newType是他的命名
go基本類(lèi)型
布爾型:bool
長(zhǎng)度:1字節(jié)
取值范圍:true掉蔬、false
注意:不能像某些語(yǔ)言一樣使用01數(shù)字來(lái)代表true或者false整型:int/uint
根據(jù)運(yùn)行平臺(tái)可能為32位(uint)或者64位(int)8位整型:int8/uint8
長(zhǎng)度:1字節(jié)
取值范圍:-128~127/0~255字節(jié)型:byte(uint8別名)
16位整型:int16/uint16
長(zhǎng)度:2字節(jié)
取值范圍:-32768~32767/0~6553532位整型:int32(rune)/uint32
長(zhǎng)度:4字節(jié)
取值范圍:(232/2~232/2-1)/(0~2^32-1)64位整型:int64/uint64
長(zhǎng)度:8字節(jié)
取值范圍:同理浮點(diǎn)型:float32/float64
長(zhǎng)度:4/8字節(jié)
精準(zhǔn)度:精確到7/15小數(shù)位復(fù)數(shù):complex64/complex128
長(zhǎng)度:8/16字節(jié)足夠保存指針的32位或64位整數(shù)型:uintptr
其他值類(lèi)型:
array廊宪、struct、string引用類(lèi)型:
slice女轿、map箭启、chan接口類(lèi)型:interface
函數(shù)類(lèi)型:func
注意區(qū)分值類(lèi)型和引用類(lèi)型,會(huì)在后面變量傳遞的時(shí)候有區(qū)別
類(lèi)型零值
零值并不等于空值蛉迹,而是當(dāng)變量被聲明為某種類(lèi)型后的默認(rèn)值傅寡,就是說(shuō)你在聲明他的時(shí)候就存在值了,通常情況下值類(lèi)型的默認(rèn)值為0,比如int赏僧,就是一個(gè)0大猛,slice就是多個(gè)或一個(gè)0扭倾,bool的默認(rèn)值為false淀零,string為空的字符串
package main
import "fmt"
func main() {
var a int
var b []int
var c string
var d bool
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
}
/*
0
[]
false
*/
類(lèi)型別名
// 一般類(lèi)型的聲明 type關(guān)鍵字
type (
newType int
type1 float32
type2 string
)
就是為類(lèi)型起一個(gè)別名,注意的是基礎(chǔ)類(lèi)型與別名之后的類(lèi)型并不完全對(duì)等膛壹,賦值等等需要轉(zhuǎn)換
單個(gè)變量的聲明與賦值
這個(gè)我剛看也有點(diǎn)愁人驾中,聲明和賦值的方法很多,并不是會(huì)簡(jiǎn)單好用的一種就夠了模聋,畢竟也要讀別人的代碼肩民,所以必須全部掌握
第一種:聲明-賦值
package main
import "fmt"
func main() {
// 聲明 var-命名-類(lèi)型
var a int
// 賦值
a = 111
fmt.Println(a) // 111
}
第二種:類(lèi)型推斷
package main
import "fmt"
func main() {
// 賦值并類(lèi)型推斷
var a = 111
fmt.Println(a) // 111
}
第三種:聲明并賦值簡(jiǎn)單寫(xiě)法
package main
import "fmt"
func main() {
// 聲明并賦值簡(jiǎn)單寫(xiě)法
a := 111
fmt.Println(a) // 111
}
這些方式不僅適用int等等這些類(lèi)型的聲明,也適用一些其他類(lèi)型的聲明链方,所以要掌握
系統(tǒng)推斷的聲明賦值前提是在使用過(guò)程中值的類(lèi)型不會(huì)發(fā)生轉(zhuǎn)變持痰,否則會(huì)拋出錯(cuò)誤
聲明賦值變量要注意的點(diǎn):
全局變量聲明不能省略
var
關(guān)鍵字換成:=
來(lái)聲明多個(gè)全局變量可以使用
var()
進(jìn)行簡(jiǎn)寫(xiě)所有的變量都可以使用類(lèi)型推斷
局部變量不可以使用
var()
方式簡(jiǎn)寫(xiě),只能使用并行方式
package main
import "fmt"
// 全局變量 支持多個(gè)變量賦值祟蚀,支持并行工窍,不可省略var
var (
a = "hello"
b = "hi"
aa, bb = 1, 2
)
func main() {
// 不可以使用括號(hào),但是可以使用并行前酿,可以省略var使用簡(jiǎn)寫(xiě)
var a, b, c, d int
a, b, c, d = 1, 2, 3, 4
// 也可以忽略賦值患雏,只用_來(lái)代替變量名,可用于多返回值但是不需要全部返回值的時(shí)候
// 上面兩句等價(jià) var a, b, c, d int = 1, 2, 3, 4
e, f, g := 5, "ss", 6
fmt.Println(a, b, c, d, e, f, g)
}
變量的類(lèi)型轉(zhuǎn)換
- go中不存在隱式轉(zhuǎn)換罢维,所有類(lèi)型轉(zhuǎn)換必須顯式聲明
- 轉(zhuǎn)換只能發(fā)生在兩種相互兼容的類(lèi)型之間
package main
import "fmt"
func main() {
var a float32 = 1.1
b := int(a)
fmt.Println(b) // 1
var c bool = true
d := int(c) // cannot convert c (type bool) to type int
}
要注意數(shù)字轉(zhuǎn)字符串的時(shí)候會(huì)轉(zhuǎn)為對(duì)應(yīng)的字母淹仑,想要真正的轉(zhuǎn)換成字符串需要庫(kù)strconv
package main
import "fmt"
import "strconv"
func main() {
var a int = 65
b := string(a)
fmt.Println(b) // A
// int轉(zhuǎn)string
c := strconv.Itoa(a)
fmt.Println(c) // 65
d, e := strconv.Atoi(c)
fmt.Println(d)
fmt.Println(e)
}
常量及運(yùn)算符
常量的定義
- 常量的值在編譯時(shí)就已經(jīng)確認(rèn)
- 常量定義格式與變量基本相同
- 等號(hào)右側(cè)必須是常量或者常量表達(dá)式(必須是常量,不能是運(yùn)行中產(chǎn)生的)
- 常量表達(dá)式中的函數(shù)必須是內(nèi)置函數(shù)(自己寫(xiě)的函數(shù)不可以)
-
++
--
作為語(yǔ)句并不作為表達(dá)式 即不能放在等號(hào)右邊
package main
import "fmt"
const a int = 2
const b = "A"
const (
c = a + 1
d = a * 3
// 沒(méi)有表達(dá)式或者常量的話(huà)會(huì)自動(dòng)選擇上一行的表達(dá)式肺孵,前提是這兩行格式相同
e
f, g = 22, 33
)
func main() {
fmt.Println(a) // 2
fmt.Println(b) // A
fmt.Println(c) // 3
fmt.Println(d) // 6
fmt.Println(e) // 6
fmt.Println(f) // 22
fmt.Println(g) // 33
}
常量的初始化規(guī)則與枚舉
- 在定義常量組時(shí)匀借,如果不提供初始值,則表示將使用上行的表達(dá)式
- 使用相同的表達(dá)式不代表具有相同的值
-
iota
是常量的計(jì)數(shù)器平窘,從0開(kāi)始吓肋,組中每定義一個(gè)常量自動(dòng)遞增1 - 通過(guò)初始化規(guī)則與
iota
可以達(dá)到枚舉的效果 - 每遇到一個(gè)
const
關(guān)鍵字,iota就會(huì)重置為0
package main
import "fmt"
const (
// 使用雙引號(hào)是會(huì)輸出字符串A初婆,單引號(hào)輸出對(duì)應(yīng)的數(shù)字
a = 'A'
b
// 此時(shí)iota為2
c = iota
d
)
const (
// 新的關(guān)鍵詞const iota從0開(kāi)始
e = iota
)
func main() {
fmt.Println(a) // 65
fmt.Println(b) // 65
fmt.Println(c) // 2
fmt.Println(d) // 3
fmt.Println(e) // 0
}
枚舉應(yīng)用
package main
import (
"fmt"
)
const (
a = 0
Monday = iota
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
)
func main() {
fmt.Println(Sunday) // 7
}
運(yùn)算符
- go語(yǔ)言中運(yùn)算符同樣遵循從左至右的運(yùn)算順序
- 優(yōu)先級(jí)(從高到低)
^ !
(一元運(yùn)算)
* / % << >> & &^
+ - | ^
(二元運(yùn)算)
== != < <= >=
<-
(專(zhuān)用與channel)
&&
||
新接觸:
>> <<
左移/右移多少位
& | ^ &^
四個(gè)位運(yùn)算符
/*
6: 0110
11: 1011
---------
兩個(gè)數(shù)位運(yùn)算先轉(zhuǎn)換為2進(jìn)制
& 0010 = 2 和
| 1111 = 15 或
^ 1101 = 13 對(duì)比過(guò)程中只存在一個(gè)1則為1
&^ 0100 = 4 如果第二個(gè)數(shù)對(duì)應(yīng)的位置為1蓬坡,則將第一個(gè)數(shù)對(duì)應(yīng)的位置轉(zhuǎn)換為0
之后再轉(zhuǎn)換回10進(jìn)制
*/
func main() {
fmt.Println(6 & 11) // 2
fmt.Println(6 | 11) // 5
fmt.Println(6 ^ 11) // 13
fmt.Println(6 &^ 11) // 4
}
單個(gè)的&變?yōu)榱宋贿\(yùn)算符,&&作為‘與’運(yùn)算符磅叛,左邊條件不成立則右邊不執(zhí)行
實(shí)現(xiàn)計(jì)算機(jī)存儲(chǔ)單位的枚舉
const (
B float64 = 1 << (iota * 10)
KB
MB
GB
TB
)
func main() {
fmt.Println(B) // 1
fmt.Println(KB) // 1024
fmt.Println(MB) // 1.048576e+06
fmt.Println(GB) // 1.073741824e+09
fmt.Println(TB) // 1.099511627776e+12
}
指針
指針屬于要深入了解的東西屑咳,
go雖然保留了指針,但是在go中并不支持指針運(yùn)算以及
->
運(yùn)算符弊琴,而是采用.
選擇符來(lái)操作指針目標(biāo)對(duì)象成員操作符
&
取變量地址兆龙,使用*
通過(guò)指針間接訪問(wèn)目標(biāo)對(duì)象默認(rèn)值為nil非NULL
package main
import (
"fmt"
)
func main() {
a := 1
// 聲明指向int的指針p
var p *int
// 賦值p
p = &a
fmt.Println(p) // 0xc420014100
fmt.Println(&a) // 0xc420014100
fmt.Println(a) // 1
}