這篇文章將為大家詳細(xì)講解有關(guān)Golang基礎(chǔ)的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
成都網(wǎng)絡(luò)公司-成都網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)10余年經(jīng)驗成就非凡,專業(yè)從事做網(wǎng)站、網(wǎng)站設(shè)計,成都網(wǎng)頁設(shè)計,成都網(wǎng)頁制作,軟文發(fā)布平臺,1元廣告等。10余年來已成功提供全面的成都網(wǎng)站建設(shè)方案,打造行業(yè)特色的成都網(wǎng)站建設(shè)案例,建站熱線:13518219792,我們期待您的來電!
package main import "fmt" func main() { fmt.Println("hello golang") }
布爾型( true 或者 false)
數(shù)字類型( 整型 int 和 浮點型 float32、float64 )
字符串類型( 字符串就是一串固定長度的字符連接起來的字符序列 )
派生類型:
指針類型(Pointer)
數(shù)組類型
結(jié)構(gòu)化類型(struct)
Channel 類型
函數(shù)類型
切片類型
接口類型(interface)
Map 類型
整形
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)
浮點型
float32 32位浮點型數(shù)
float64 64位浮點型數(shù)
complex64 32 位實數(shù)和虛數(shù)
complex128 64 位實數(shù)和虛數(shù)
其他數(shù)字類型
byte 類似 uint8
rune 類似 int32
uint 32 或 64 位
int 與 uint 一樣大小
uintptr 無符號整型,用于存放一個指針
// 聲明一個變量 var identifier type // 可以一次聲明多個變量 var identifier1, identifier2 type // 根據(jù)值自行判定變量類型 var v_name = value // 簡短形式 省略 var, 注意 := 左側(cè)如果沒有聲明新的變量 v_name := value
// 聲明一個常量 const identifier [type] = value // 顯式類型定義 const b string = "abc" // 隱式類型定義 const b = "abc" // 多個相同類型的聲明(隱式類型定義) const c_name1, c_name2 = value1, value2
iota,特殊常量,可以認(rèn)為是一個可以被編譯器修改的常量
iota 在 const關(guān)鍵字出現(xiàn)時將被重置為 0(const 內(nèi)部的第一行之前),const 中每新增一行常量聲明將使 iota 計數(shù)一次(iota 可理解為 const 語句塊中的行索引)。
iota 可以被用作枚舉值
package main import "fmt" func main() { const ( a = iota //0 b //1 c //2 d = "ha" //獨立值,iota += 1 e //"ha" iota += 1 f = 100 //iota +=1 g //100 iota +=1 h = iota //7,恢復(fù)計數(shù) i //8 ) fmt.Println(a,b,c,d,e,f,g,h,i) }
運行結(jié)果
0 1 2 ha ha 100 100 7 8
第一個 iota 等于 0,每當(dāng) iota 在新的一行被使用時,它的值都會自動加 1
package main import "fmt" func main() { var a = 12 if a > 10 { fmt.Println("a>10") } else { fmt.Println("a<=10") } }
運行結(jié)果
a>10
package main import "fmt" func main() { var a = 12 switch a { case 1: fmt.Println(1) case 2: fmt.Println(2) case 12: fmt.Println(12) default: fmt.Println(a) } }
運行結(jié)果
12
使用 fallthrough 會強(qiáng)制執(zhí)行后面的 case 語句,fallthrough 不會判斷下一條 case 的表達(dá)式結(jié)果是否為 true
package main import "fmt" func main() { var a = 1 switch a { case 1: fmt.Println(1) fallthrough case 2: fmt.Println(2) case 12: fmt.Println(12) default: fmt.Println(a) } }
運行結(jié)果
1 2
select 是 Go 中的一個控制結(jié)構(gòu),類似于用于通信的 switch 語句。每個 case 必須是一個通信操作,要么是發(fā)送要么是接收。
select 隨機(jī)執(zhí)行一個可運行的 case。如果沒有 case 可運行,它將阻塞,直到有 case 可運行。一個默認(rèn)的子句應(yīng)該總是可運行的。
package main import "fmt" func main() { var c1, c2, c3 chan int var i1, i2 int select { case i1 = <-c1: fmt.Printf("received ", i1, " from c1\n") case c2 <- i2: fmt.Printf("sent ", i2, " to c2\n") case i3, ok := <-c3: if ok { fmt.Printf("received ", i3, " from c3\n") } else { fmt.Printf("c3 is closed\n") } default: fmt.Printf("no communication\n") } }
運行結(jié)果
no communication
package main import "fmt" func main() { for i := 1; i < 10; i++ { fmt.Println(i) } }
package main import "fmt" func main() { var i = 1 for i < 10 { fmt.Println(i) i++ } }
運行結(jié)果
1 2 3 4 5 6 7 8 9
死循環(huán)
for { }
package main import "fmt" func main() { test(1) } func test(i int) int { for i < 10 { fmt.Println(i) i++ } return i }
運行結(jié)果
1 2 3 4 5 6 7 8 9
package main import "fmt" func main() { i := test(1, 9) fmt.Println("最大值為:", i) } func test(i, j int) int { if i > j { return i } else { return j } }
運行結(jié)果
最大值為: 9
package main import "fmt" func main() { s, s2 := test("hello", "go") fmt.Println(s, s2) } func test(i, j string) (string, string) { return i, j }
運行結(jié)果
hello go
package main import "fmt" func main() { var a = 3 var b = 4 fmt.Println("值傳遞運行前a=", a, "b=", b) test1(a, b) fmt.Println("值傳遞運行后a=", a, "b=", b) fmt.Println("===============================================") var i = 1 var j = 2 fmt.Println("引用傳遞運行前i=", i, "j=", j) test2(&i, &j) fmt.Println("引用傳遞運行后i=", i, "j=", j) } // 值傳遞 func test1(i, j int) (int, int) { var temp int temp = i i = j j = temp return i, j } // 引用傳遞 func test2(i, j *int) (int, int) { var temp int temp = *i *i = *j *j = temp return *i, *j }
運行結(jié)果
值傳遞運行前a= 3 b= 4 值傳遞運行后a= 3 b= 4 =============================================== 引用傳遞運行前i= 1 j= 2 引用傳遞運行后i= 2 j= 1
package main import "fmt" func main() { funcA := func(a int) int { return a } fmt.Println(funcA(12)) }
運行結(jié)果
12
Go 語言支持匿名函數(shù),可作為閉包。匿名函數(shù)是一個"內(nèi)聯(lián)"語句或表達(dá)式。匿名函數(shù)的優(yōu)越性在于可以直接使用函數(shù)內(nèi)的變量,不必申明。
package main import "fmt" func main() { next := getSequence() fmt.Println(next()) fmt.Println(next()) fmt.Println(next()) } func getSequence() func() int { a := 1 return func() int { a++ return a } }
運行結(jié)果
2 3 4
Go 語言中同時有函數(shù)和方法。一個方法就是一個包含了接受者的函數(shù),接受者可以是命名類型或者結(jié)構(gòu)體類型的一個值或者是一個指針。所有給定類型的方法屬于該類型的方法集
package main import "fmt" type Circle struct { radius float64 } func (circle Circle) getPerimeter() float64 { return 3.14 * circle.radius * 2 } func main() { var circle Circle circle.radius = 10 fmt.Println(circle.getPerimeter()) }
運行結(jié)果
62.800000000000004
Go 語言中變量可以在三個地方聲明:
函數(shù)內(nèi)定義的變量稱為局部變量
函數(shù)外定義的變量稱為全局變量
函數(shù)定義中的變量稱為形式參數(shù)
package main import "fmt" // 全局變量 var a = 1 func main() { // 局部變量 var b = 2 test(a) test(b) } // 形式參數(shù) func test(a int) { fmt.Println(a) }
數(shù)組是具有相同唯一類型的一組已編號且長度固定的數(shù)據(jù)項序列,這種類型可以是任意的原始類型例如整形、字符串或者自定義類型
// 形式 var variable_name [SIZE] variable_type // 舉例 var balance [10] float32
// 初始化一個長度為5的float32數(shù)組 var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0} // 如果忽略 [] 中的數(shù)字不設(shè)置數(shù)組大小 var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0} balance[6] = 60.0
var a float32 = balance[5]
一個指針變量指向了一個值的內(nèi)存地址
// 形式 var var_name *var-type // 舉例 var ip *int /* 指向整型*/ var fp *float32 /* 指向浮點型 */
package main import "fmt" func main() { var a int = 20 /* 聲明實際變量 */ var ip *int /* 聲明指針變量 */ ip = &a /* 指針變量的存儲地址 */ fmt.Printf("a 變量的地址是: %x\n", &a) /* 指針變量的存儲地址 */ fmt.Printf("ip 變量儲存的指針地址: %x\n", ip) /* 使用指針訪問值 */ fmt.Printf("*ip 變量的值: %d\n", *ip) }
運行結(jié)果
a 變量的地址是: c00000a0b0 ip 變量儲存的指針地址: c00000a0b0 *ip 變量的值: 20
當(dāng)一個指針被定義后沒有分配到任何變量時,它的值為 nil。
nil 指針也稱為空指針。一個指針變量通??s寫為 ptr。
package main import "fmt" func main() { var ip *int /* 聲明指針變量 */ /* 指針變量的存儲地址 */ fmt.Printf("ip 的值為: %x\n", ip) }
運行結(jié)果
ip 的值為: 0
if(ptr != nil) /* ptr 不是空指針 */ if(ptr == nil) /* ptr 是空指針 */
package main import "fmt" func main() { a := []int{10, 100, 200} // 遍歷數(shù)組 for i := 0; i < len(a); i++ { fmt.Printf("a[%d] = %d\n", i, a[i]) } fmt.Println("==================================") // 有一種情況,我們可能需要保存數(shù)組,這樣我們就需要使用到指針。 // 以下聲明了整型指針數(shù)組: var ptr [3]*int for i := 0; i < len(a); i++ { /* 整數(shù)地址賦值給指針數(shù)組 */ ptr[i] = &a[i] } for i := 0; i < len(ptr); i++ { fmt.Printf("a[%d] = %d\n", i, *ptr[i]) } }
運行結(jié)果
a[0] = 10 a[1] = 100 a[2] = 200 ================================== a[0] = 10 a[1] = 100 a[2] = 200
如果一個指針變量存放的又是另一個指針變量的地址,則稱這個指針變量為指向指針的指針變量。 指向指針的指針變量聲明格式
var ptr **int;
package main import "fmt" func main() { var a int var ptr *int var pptr **int a = 3000 /* 指針 ptr 地址 */ ptr = &a /* 指向指針 ptr 地址 */ pptr = &ptr /* 獲取 pptr 的值 */ fmt.Printf("變量 a = %d\n", a) fmt.Printf("指針變量 *ptr = %d\n", *ptr) fmt.Printf("指向指針的指針變量 **pptr = %d\n", **pptr) }
運行結(jié)果
變量 a = 3000 指針變量 *ptr = 3000 指向指針的指針變量 **pptr = 3000
package main import "fmt" func main() { var a = 3 var b = 4 fmt.Println("值傳遞運行前a=", a, "b=", b) test1(a, b) fmt.Println("值傳遞運行后a=", a, "b=", b) fmt.Println("===============================================") var i = 1 var j = 2 fmt.Println("引用傳遞運行前i=", i, "j=", j) test2(&i, &j) fmt.Println("引用傳遞運行后i=", i, "j=", j) } // 值傳遞 func test1(i, j int) (int, int) { var temp int temp = i i = j j = temp return i, j } // 引用傳遞 func test2(i, j *int) (int, int) { var temp int temp = *i *i = *j *j = temp return *i, *j }
運行結(jié)果
值傳遞運行前a= 3 b= 4 值傳遞運行后a= 3 b= 4 =============================================== 引用傳遞運行前i= 1 j= 2 引用傳遞運行后i= 2 j= 1
結(jié)構(gòu)體是由一系列具有相同類型或不同類型的數(shù)據(jù)構(gòu)成的數(shù)據(jù)集合。
結(jié)構(gòu)體表示一項記錄,比如保存圖書館的書籍記錄,每本書有以下屬性:
Title :標(biāo)題 Author : 作者 Subject:學(xué)科 ID:書籍ID
type struct_variable_type struct { member definition member definition ... member definition }
一旦定義了結(jié)構(gòu)體類型,它就能用于變量的聲明,語法格式如下:
variable_name := structure_variable_type {value1, value2...valuen} 或 variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}
package main import "fmt" // 一、定義結(jié)構(gòu)體 type Books struct { title string author string subject string book_id int } func main() { // 創(chuàng)建一個新的結(jié)構(gòu)體 fmt.Println(Books{"Go 語言", "Google", "Go 語言教程", 6495407}) // 也可以使用 key => value 格式 fmt.Println(Books{title: "Go 語言", author: "Google", subject: "Go 語言教程", book_id: 6495407}) // 忽略的字段為 0 或 空 fmt.Println(Books{title: "Go 語言", author: "Google"}) fmt.Println("=========================") // 二、訪問結(jié)構(gòu)體成員 /* book 2 描述 */ var Book2 Books Book2.title = "Python 教程" Book2.author = "Python" Book2.subject = "Python 語言教程" Book2.book_id = 6495700 /* 打印 Book2 信息 */ fmt.Printf("Book 2 title : %s\n", Book2.title) fmt.Printf("Book 2 author : %s\n", Book2.author) fmt.Printf("Book 2 subject : %s\n", Book2.subject) fmt.Printf("Book 2 book_id : %d\n", Book2.book_id) fmt.Println("=========================") // 三、結(jié)構(gòu)體作為函數(shù)參數(shù) printBook(Book2) fmt.Println("=========================") // 四、結(jié)構(gòu)體指針 printBook2(&Book2) } func printBook(book Books) { fmt.Printf("Book title : %s\n", book.title) fmt.Printf("Book author : %s\n", book.author) fmt.Printf("Book subject : %s\n", book.subject) fmt.Printf("Book book_id : %d\n", book.book_id) } func printBook2(book *Books) { fmt.Printf("Book title : %s\n", book.title) fmt.Printf("Book author : %s\n", book.author) fmt.Printf("Book subject : %s\n", book.subject) fmt.Printf("Book book_id : %d\n", book.book_id) }
運行結(jié)果
{Go 語言 Google Go 語言教程 6495407} {Go 語言 Google Go 語言教程 6495407} {Go 語言 Google 0} ========================= Book 2 title : Python 教程 Book 2 author : Python Book 2 subject : Python 語言教程 Book 2 book_id : 6495700 ========================= Book title : Python 教程 Book author : Python Book subject : Python 語言教程 Book book_id : 6495700 ========================= Book title : Python 教程 Book author : Python Book subject : Python 語言教程 Book book_id : 6495700
Go 數(shù)組的長度不可改變,與數(shù)組相比切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。
var identifier []type
var slice1 []type = make([]type, len) 或者簡寫 slice1 := make([]type, len) 指定長度
make([]T, length, capacity) 指定容量
package main import "fmt" func main() { // 切片初始化 var slice = []int{1, 2, 3} // 從下標(biāo)startIndex到endIndex-1 下的元素 切片截取 fmt.Println(slice[0:2]) fmt.Println(slice[:2]) fmt.Println(slice[0:]) fmt.Println("=======================") // len() 和 cap() 函數(shù) fmt.Printf("len=%d cap=%d slice=%v\n", len(slice), cap(slice), slice) fmt.Println("=======================") // 空切片 var numbers []int fmt.Printf("len=%d cap=%d slice=%v\n", len(numbers), cap(numbers), numbers) if numbers == nil { fmt.Printf("切片是空的\n") } fmt.Println("=======================") // append() 和 copy() 函數(shù) var numbers1 []int // append() 追加 numbers1 = append(numbers1, 1) numbers1 = append(numbers1, 2, 3, 4) fmt.Printf("len=%d cap=%d slice=%v\n", len(numbers1), cap(numbers1), numbers1) fmt.Println("=======================") // copy() 復(fù)制 /* 創(chuàng)建切片 numbers2 是之前切片的兩倍容量*/ numbers2 := make([]int, len(numbers1), (cap(numbers1))*2) /* 拷貝 numbers1 的內(nèi)容到 numbers2 */ copy(numbers2, numbers1) fmt.Printf("len=%d cap=%d slice=%v\n", len(numbers2), cap(numbers2), numbers2) }
運行結(jié)果
[1 2] [1 2] [1 2 3] ======================= len=3 cap=3 slice=[1 2 3] ======================= len=0 cap=0 slice=[] 切片是空的 ======================= len=4 cap=4 slice=[1 2 3 4] ======================= len=4 cap=8 slice=[1 2 3 4]
package main import "fmt" func main() { //這是我們使用range去求一個slice的和。使用數(shù)組跟這個很類似 nums := []int{2, 3, 4} sum := 0 for _, num := range nums { sum += num } fmt.Println("sum:", sum) //在數(shù)組上使用range將傳入index和值兩個變量。上面那個例子我們不需要使用該元素的序號,所以我們使用空白符"_"省略了。有時侯我們確實需要知道它的索引。 for i, num := range nums { if num == 3 { fmt.Println("index:", i) } } //range也可以用在map的鍵值對上。 kvs := map[string]string{"a": "apple", "b": "banana"} for k, v := range kvs { fmt.Printf("%s -> %s\n", k, v) } //range也可以用來枚舉Unicode字符串。第一個參數(shù)是字符的索引,第二個是字符(Unicode的值)本身。 for i, c := range "go" { fmt.Println(i, c) } }
運行結(jié)果
sum: 9 index: 1 a -> apple b -> banana 0 103 1 111
Map 是一種無序的鍵值對的集合。Map 最重要的一點是通過 key 來快速檢索數(shù)據(jù),key 類似于索引,指向數(shù)據(jù)的值。
/* 聲明變量,默認(rèn) map 是 nil */ var map_variable map[key_data_type]value_data_type /* 使用 make 函數(shù) */ map_variable := make(map[key_data_type]value_data_type)
如果不初始化 map,那么就會創(chuàng)建一個 nil map。nil map 不能用來存放鍵值對
package main import "fmt" func main() { var countryCapitalMap = make(map[string]string) /* map插入key - value對,各個國家對應(yīng)的首都 */ countryCapitalMap["France"] = "巴黎" countryCapitalMap["Italy"] = "羅馬" countryCapitalMap["Japan"] = "東京" countryCapitalMap["India "] = "新德里" /*使用鍵輸出地圖值 */ for country := range countryCapitalMap { fmt.Println(country, "首都是", countryCapitalMap[country]) } /*查看元素在集合中是否存在 */ capital, ok := countryCapitalMap["American"] /*如果確定是真實的,則存在,否則不存在 */ /*fmt.Println(capital) */ /*fmt.Println(ok) */ if ok { fmt.Println("American 的首都是", capital) } else { fmt.Println("American 的首都不存在") } fmt.Println("========================") // delete() 函數(shù) for country := range countryCapitalMap { fmt.Println(country, "首都是", countryCapitalMap[country]) } // 刪除元素 delete(countryCapitalMap, "France") fmt.Println("法國條目被刪除") for country := range countryCapitalMap { fmt.Println(country, "首都是", countryCapitalMap[country]) } }
運行結(jié)果
France 首都是 巴黎 Italy 首都是 羅馬 Japan 首都是 東京 India 首都是 新德里 American 的首都不存在 ======================== India 首都是 新德里 France 首都是 巴黎 Italy 首都是 羅馬 Japan 首都是 東京 法國條目被刪除 Japan 首都是 東京 India 首都是 新德里 Italy 首都是 羅馬
遞歸,就是在運行的過程中調(diào)用自己
package main import "fmt" func main() { var i int = 15 fmt.Printf("%d 的階乘是 %d\n", i, Factorial(uint64(i))) } func Factorial(n uint64) (result uint64) { if n > 0 { result = n * Factorial(n-1) return result } return 1 }
運行結(jié)果
15 的階乘是 1307674368000
package main import "fmt" func main() { var i int for i = 0; i < 10; i++ { fmt.Printf("%d\t", fibonacci(i)) } } func fibonacci(n int) int { if n < 2 { return n } return fibonacci(n-2) + fibonacci(n-1) }
運行結(jié)果
0 1 1 2 3 5 8 13 21 34
類型轉(zhuǎn)換用于將一種數(shù)據(jù)類型的變量轉(zhuǎn)換為另外一種類型的變量。
type_name(expression)
package main import "fmt" func main() { var sum int = 17 var count int = 5 var mean float32 mean = float32(sum) / float32(count) fmt.Printf("mean 的值為: %f\n", mean) }
運行結(jié)果
mean 的值為: 3.400000
package main import "fmt" type Phone interface { call() } type NokiaPhone struct { } type IPhone struct { } func main() { n := new(NokiaPhone) n.call() i := new(IPhone) i.call() } func (NokiaPhone) call() { fmt.Println("nokiaPhone") } func (IPhone) call() { fmt.Println("IPhone") }
運行結(jié)果
nokiaPhone IPhone
Go 語言通過內(nèi)置的錯誤接口提供了非常簡單的錯誤處理機(jī)制。
error類型是一個接口類型,這是它的定義
type error interface { Error() string }
我們可以在編碼中通過實現(xiàn) error 接口類型來生成錯誤信息。
函數(shù)通常在最后的返回值中返回錯誤信息。使用errors.New 可返回一個錯誤信息
package main import ( "errors" "fmt" ) func main() { _, err := Sqrt(-1) if err != nil { fmt.Println(err) } } func Sqrt(f float64) (float64, error) { if f < 0 { return 0, errors.New("math: square root of negative number") } // 實現(xiàn) return f, nil }
運行結(jié)果
math: square root of negative number
Go 語言支持并發(fā),我們只需要通過 go 關(guān)鍵字來開啟 goroutine 即可。
goroutine 是輕量級線程,goroutine 的調(diào)度是由 Golang 運行時進(jìn)行管理的。
goroutine 語法格式:
go 函數(shù)名( 參數(shù)列表 )
Go 允許使用 go 語句開啟一個新的運行期線程, 即 goroutine,以一個不同的、新創(chuàng)建的 goroutine 來執(zhí)行一個函數(shù)。 同一個程序中的所有 goroutine 共享同一個地址空間。
package main import ( "fmt" "time" ) func main() { go say("world") say("hello") } func say(s string) { for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } }
運行結(jié)果
hello world world hello hello world world hello hello
通道(channel)是用來傳遞數(shù)據(jù)的一個數(shù)據(jù)結(jié)構(gòu)。
通道可用于兩個 goroutine 之間通過傳遞一個指定類型的值來同步運行和通訊。操作符 <- 用于指定通道的方向,發(fā)送或接收。如果未指定方向,則為雙向通道。 聲明一個通道,通道在使用前必須先創(chuàng)建:
ch := make(chan int)
注意:默認(rèn)情況下,通道是不帶緩沖區(qū)的。發(fā)送端發(fā)送數(shù)據(jù),同時必須有接收端相應(yīng)的接收數(shù)據(jù)。
package main import ( "fmt" ) func main() { s := []int{7, 2, 8, -9, 4, 0} c := make(chan int) go sum(s[:len(s)/2], c) go sum(s[len(s)/2:], c) x, y := <-c, <-c // 從通道 c 中接收 fmt.Println(x, y, x+y) } func sum(s []int, c chan int) { sum := 0 for _, v := range s { sum += v } c <- sum // 把 sum 發(fā)送到通道 c }
運行結(jié)果
-5 17 12
通道可以設(shè)置緩沖區(qū),通過 make 的第二個參數(shù)指定緩沖區(qū)大小:
ch := make(chan int, 100)
帶緩沖區(qū)的通道允許發(fā)送端的數(shù)據(jù)發(fā)送和接收端的數(shù)據(jù)獲取處于異步狀態(tài),就是說發(fā)送端發(fā)送的數(shù)據(jù)可以放在緩沖區(qū)里面,可以等待接收端去獲取數(shù)據(jù),而不是立刻需要接收端去獲取數(shù)據(jù)。
不過由于緩沖區(qū)的大小是有限的,所以還是必須有接收端來接收數(shù)據(jù)的,否則緩沖區(qū)一滿,數(shù)據(jù)發(fā)送端就無法再發(fā)送數(shù)據(jù)了。
注意:如果通道不帶緩沖,發(fā)送方會阻塞直到接收方從通道中接收了值。如果通道帶緩沖,發(fā)送方則會阻塞直到發(fā)送的值被拷貝到緩沖區(qū)內(nèi);如果緩沖區(qū)已滿,則意味著需要等待直到某個接收方獲取到一個值。接收方在有值可以接收之前會一直阻塞。
package main import ( "fmt" ) func main() { // 這里我們定義了一個可以存儲整數(shù)類型的帶緩沖通道 // 緩沖區(qū)大小為2 ch := make(chan int, 2) // 因為 ch 是帶緩沖的通道,我們可以同時發(fā)送兩個數(shù)據(jù) // 而不用立刻需要去同步讀取數(shù)據(jù) ch <- 1 ch <- 2 // 獲取這兩個數(shù)據(jù) fmt.Println(<-ch) fmt.Println(<-ch) }
運行結(jié)果
1 2
Go 通過 range 關(guān)鍵字來實現(xiàn)遍歷讀取到的數(shù)據(jù),類似于與數(shù)組或切片。格式如下:
v, ok := <-ch
package main import ( "fmt" ) func main() { c := make(chan int, 10) go fibonacci(cap(c), c) // range 函數(shù)遍歷每個從通道接收到的數(shù)據(jù),因為 c 在發(fā)送完 10 個 // 數(shù)據(jù)之后就關(guān)閉了通道,所以這里我們 range 函數(shù)在接收到 10 個數(shù)據(jù) // 之后就結(jié)束了。如果上面的 c 通道不關(guān)閉,那么 range 函數(shù)就不 // 會結(jié)束,從而在接收第 11 個數(shù)據(jù)的時候就阻塞了。 for i := range c { fmt.Println(i) } } func fibonacci(n int, c chan int) { x, y := 0, 1 for i := 0; i < n; i++ { c <- x x, y = y, x+y } // 關(guān)閉通道 close(c) }
運行結(jié)果
0 1 1 2 3 5 8 13 21 34
關(guān)于“Golang基礎(chǔ)的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
名稱欄目:Golang基礎(chǔ)的示例分析
分享地址:http://muchs.cn/article28/iegpjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、App開發(fā)、做網(wǎng)站、網(wǎng)站設(shè)計、網(wǎng)站排名、用戶體驗
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)