bool, int, float, complex, ...
懶得多說痴奏,大體跟C++也差不多梦抢,int, uint, int16, uint32什么的案糙;float32/float64地啰;complex是復(fù)數(shù)策彤,原生支持栓袖;
array, slice, range
數(shù)組顿膨,長度固定,跟其他語言的數(shù)組其實(shí)也差不太多:
var numbers = [3]int{1,2,3}
var numbers = [...]int{1,2,3} //這里長度也可以省略
var length = len(numbers)
如果一個(gè)數(shù)組沒有賦值叽赊,則默認(rèn)值為[length[type{0,0,0...}
切片(slice)是以數(shù)組作為底層數(shù)據(jù)結(jié)構(gòu)的一種引用類型恋沃,每個(gè)切片都會(huì)有一個(gè)對(duì)應(yīng)的數(shù)組,如果沒有進(jìn)行初始化則其值為nil:
var nums := []int{2, 3, 4}
// 其他訪問方式等基本與數(shù)組一致
簡單的說必指,切片可以看成一個(gè)結(jié)構(gòu)體囊咏,里面保存了容量、元素個(gè)數(shù)與底層的一個(gè)數(shù)組塔橡;多個(gè)切片可以指向同一個(gè)數(shù)組梅割;需要詳細(xì)了解其中的實(shí)現(xiàn),有一些需要注意的問題葛家,比如作為函數(shù)參數(shù)時(shí)發(fā)生了什么户辞,什么時(shí)候會(huì)導(dǎo)致誤修改其他數(shù)組中的值等。
range用于在for循環(huán)中迭代array癞谒、slice底燎、map等中的元素,數(shù)組與切片中返回索引和值弹砚,map中則返回key-value對(duì):
nums := []int{2,3,4}
for _, num := range nums {
...
}
string
通常為UTF-8編碼双仍,分為解釋字符串("test")與非解釋字符串(`test`),解釋字符串中相關(guān)的轉(zhuǎn)義字符會(huì)被替換桌吃,而非解釋字符串則不會(huì)轉(zhuǎn)義朱沃,且支持換行。
與C/C++不一樣茅诱,go中的字符串根據(jù)長度限定逗物,而非以‘\0’結(jié)尾。
struct
跟其他語言的也差不太多瑟俭,不過變量的首字母有特殊的含義翎卓,首字母小寫的變量在包外無法引用。
type Books struct {
title string
author string
subject string
book_id int
}
var Book1 Books
Book1.title = "xxx"
go中還有個(gè)東西叫struct tag尔当,由于go中命名一般都用駝峰方式且首字母的大小寫具有語法含義莲祸,所以有時(shí)候在進(jìn)行一些數(shù)據(jù)交互(舉例:轉(zhuǎn)json格式)時(shí)會(huì)需要用其他的屬性名作為鍵值。這時(shí)可以用tag在結(jié)構(gòu)體成員后面加一些字符串:
type User struct {
UserId int `json:"user_id"`
UserName string `json:"user_name"`
}
tag中的內(nèi)容可以通過反射獲取椭迎,這里僅作了解锐帜。
map
go中的map基于hash實(shí)現(xiàn),無序畜号,不要依賴map的遍歷順序缴阎。用法其實(shí)跟STL中的map也差不多,不過需要初始化简软。
var countryCapitalMap map[string]string
countryCapitalMap := make(map[string]string)
countryCapitalMap["China"] = "Beijing"
countryCapitalMap ["Japan"] = "Tokyo"
delete(countryCapitalMap, "Japan")
channel
channel是go中的一個(gè)核心類型蛮拔,用于通信述暂,可以將它看成一個(gè)管道:
ch <- v // 發(fā)送值v到Channel ch中
v := <-ch // 從Channel ch中接收數(shù)據(jù),并賦值給v
可以在多個(gè)goroutine中讀寫同一個(gè)channel建炫,不必考慮額外的同步措施畦韭;
可以做為一個(gè)FIFO隊(duì)列,接收數(shù)據(jù)的順序與發(fā)送數(shù)據(jù)的順序是一致的肛跌;
缺省狀態(tài)下艺配,發(fā)送和接收會(huì)一直阻塞直至另一端準(zhǔn)備好,這種方式可以用來同步goroutine衍慎,而不必使用鎖或條件變量转唉;當(dāng)然在設(shè)置了buffer的情況下就還要考慮buffer滿沒滿了;
interface
C++中通過抽象類實(shí)現(xiàn)接口稳捆,java中也有interface關(guān)鍵字赠法,但是它們都需要顯式的聲明實(shí)現(xiàn)了某個(gè)接口,例如 Class A : public interfaceClassB乔夯,這稱之為侵入式接口砖织。而go中的接口為非侵入式接口,某個(gè)類只要實(shí)現(xiàn)了接口所要求的所有函數(shù)驯嘱,我們就說這個(gè)類實(shí)現(xiàn)了該接口镶苞。這樣有幾個(gè)好處:
1喳坠、去掉了繁雜的繼承體系鞠评;
2、實(shí)現(xiàn)類的時(shí)候只需要關(guān)心自己應(yīng)該提供的方法壕鹉,不需要糾結(jié)接口的拆分剃幌;
3、不需要為了實(shí)現(xiàn)一個(gè)接口而導(dǎo)入一個(gè)包晾浴,因?yàn)槎嘁靡粋€(gè)外部的包就意味著更多的耦合负乡;
前面提到,一個(gè)類型如果實(shí)現(xiàn)了某個(gè)interface的所有方法就說該類型實(shí)現(xiàn)了這個(gè)interface脊凰,而空的interface沒有方法抖棘, 所以可以認(rèn)為所有的類型都實(shí)現(xiàn)了空interface,所以空的interface可以用來作為函數(shù)參數(shù)狸涌,它可以接受任何類型:
func doSomething(v interface{}) {}