国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

channel通道詳解~Go進階

這篇具有很好參考價值的文章主要介紹了channel通道詳解~Go進階。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

channel通道

通道可以被認為是Goroutines通信的管道。類似于管道中的水從一端到另一端的流動,數(shù)據(jù)可以從一端發(fā)送到另一端,通過通道接收。

在前面講Go語言的并發(fā)時候,我們就說過,當多個Goroutine想實現(xiàn)共享數(shù)據(jù)的時候,雖然也提供了傳統(tǒng)的同步機制,但是Go語言強烈建議的是使用Channel通道來實現(xiàn)Goroutines之間的通信。

“不要通過共享內(nèi)存來通信,而應該通過通信來共享內(nèi)存” 這是一句風靡golang社區(qū)的經(jīng)典語

Go語言中,要傳遞某個數(shù)據(jù)給另一個goroutine(協(xié)程),可以把這個數(shù)據(jù)封裝成一個對象,然后把這個對象的指針傳入某個channel中,另外一個goroutine從這個channel中讀出這個指針,并處理其指向的內(nèi)存對象。Go從語言層面保證同一個時間只有一個goroutine能夠訪問channel里面的數(shù)據(jù),為開發(fā)者提供了一種優(yōu)雅簡單的工具,所以Go的做法就是使用channel來通信,通過通信來傳遞內(nèi)存數(shù)據(jù),使得內(nèi)存數(shù)據(jù)在不同的goroutine中傳遞,而不是使用共享內(nèi)存來通信。

什么是通道

通道的概念

通道是什么,通道就是goroutine之間的通道。它可以讓goroutine之間相互通信。

每個通道都有與其相關的類型。該類型是通道允許傳輸?shù)臄?shù)據(jù)類型。(通道的零值為nil。nil通道沒有任何用處,因此通道必須使用類似于map和切片的方法來定義。)

通道的聲明

聲明一個通道和定義一個變量的語法一樣:

//聲明通道
var 通道名 chan 數(shù)據(jù)類型
//創(chuàng)建通道:如果通道為nil(就是不存在),就需要先創(chuàng)建通道
通道名 = make(chan 數(shù)據(jù)類型)

示例代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-532359.html

package main

import "fmt"

func main() {
	var a chan int
	if a == nil {
		fmt.Println("channel 是 nil 的, 不能使用,需要先創(chuàng)建通道。。")
		a = make(chan int)
		fmt.Printf("數(shù)據(jù)類型是: %T", a)
	}
}

運行結果:

channel 是 nil 的, 不能使用,需要先創(chuàng)建通道。。
數(shù)據(jù)類型是: chan int

也可以簡短的聲明:

a := make(chan int) 

channel的數(shù)據(jù)類型

channel是引用類型的數(shù)據(jù),在作為參數(shù)傳遞的時候,傳遞的是內(nèi)存地址。

示例代碼:

package main

import (
	"fmt"
)

func main() {
	ch1 := make(chan int)
	fmt.Printf("%T,%p\n",ch1,ch1)

	test1(ch1)

}

func test1(ch chan int){
	fmt.Printf("%T,%p\n",ch,ch)
}

運行結果:

chan int,0xc00001e180
chan int,0xc00001e180

我們能夠看到,ch和ch1的地址是一樣的,說明它們是同一個通道。

通道的注意點

Channel通道在使用的時候,有以下幾個注意點:

  • 1.用于goroutine,傳遞消息的。

  • 2.通道,每個都有相關聯(lián)的數(shù)據(jù)類型,
    nil chan,不能使用,類似于nil map,不能直接存儲鍵值對

  • 3.使用通道傳遞數(shù)據(jù):<-
    chan <- data,發(fā)送數(shù)據(jù)到通道。向通道中寫數(shù)據(jù)
    data <- chan,從通道中獲取數(shù)據(jù)。從通道中讀數(shù)據(jù)

  • 4.阻塞:
    發(fā)送數(shù)據(jù):chan <- data,阻塞的,直到另一條goroutine,讀取數(shù)據(jù)來解除阻塞
    讀取數(shù)據(jù):data <- chan,也是阻塞的。直到另一條goroutine,寫出數(shù)據(jù)解除阻塞。

  • 5.本身channel就是同步的,意味著同一時間,只能有一條goroutine來操作。

最后:通道是goroutine之間的連接,所以通道的發(fā)送和接收必須處在不同的goroutine中。

通道的使用語法

發(fā)送和接收

發(fā)送和接收的語法:

data := <- a // read from channel a  
a <- data // write to channel a

在通道上箭頭的方向指定數(shù)據(jù)是發(fā)送還是接收。

另外:

v, ok := <- a //從一個channel中讀取

發(fā)送和接收默認是阻塞的

一個通道發(fā)送和接收數(shù)據(jù),默認是阻塞的。當一個數(shù)據(jù)被發(fā)送到通道時,在發(fā)送語句中被阻塞,直到另一個Goroutine從該通道讀取數(shù)據(jù)。相對地,當從通道讀取數(shù)據(jù)時,讀取被阻塞,直到一個Goroutine將數(shù)據(jù)寫入該通道。

這些通道的特性是幫助Goroutines有效地進行通信,而無需像使用其他編程語言中非常常見的顯式鎖或條件變量。

示例代碼:

package main

import "fmt"

func main() {
	var ch1 chan bool       //聲明,沒有創(chuàng)建
	fmt.Println(ch1)        //<nil>
	fmt.Printf("%T\n", ch1) //chan bool
	ch1 = make(chan bool)   //0xc0000a4000,是引用類型的數(shù)據(jù)
	fmt.Println(ch1)

	go func() {
		for i := 0; i < 10; i++ {
			fmt.Println("子goroutine中,i:", i)
		}
		// 循環(huán)結束后,向通道中寫數(shù)據(jù),表示要結束了。。
		ch1 <- true

		fmt.Println("結束。。")

	}()

	data := <-ch1 // 從ch1通道中讀取數(shù)據(jù)
	fmt.Println("data-->", data)
	fmt.Println("main。。over。。。。")
}

運行結果:

<nil>
chan bool
0xc000086120
子goroutine中,i: 0
子goroutine中,i: 1
子goroutine中,i: 2
子goroutine中,i: 3
子goroutine中,i: 4
子goroutine中,i: 5
子goroutine中,i: 6
子goroutine中,i: 7
子goroutine中,i: 8
子goroutine中,i: 9
結束。。
data--> true
main。。over。。。。

在上面的程序中,我們先創(chuàng)建了一個chan bool通道。然后啟動了一條子Goroutine,并循環(huán)打印10個數(shù)字。然后我們向通道ch1中寫入輸入true。然后在主goroutine中,我們從ch1中讀取數(shù)據(jù)。這一行代碼是阻塞的,這意味著在子Goroutine將數(shù)據(jù)寫入到該通道之前,主goroutine將不會執(zhí)行到下一行代碼。因此,我們可以通過channel實現(xiàn)子goroutine和主goroutine之間的通信。當子goroutine執(zhí)行完畢前,主goroutine會因為讀取ch1中的數(shù)據(jù)而阻塞。從而保證了子goroutine會先執(zhí)行完畢。這就消除了對時間的需求。在之前的程序中,我們要么讓主goroutine進入睡眠,以防止主要的Goroutine退出。要么通過WaitGroup來保證子goroutine先執(zhí)行完畢,主goroutine才結束。

示例代碼:以下代碼加入了睡眠,可以更好的理解channel的阻塞

package main

import (
	"fmt"
	"time"
)

func main() {
	ch1 := make(chan int)
	done := make(chan bool) // 通道
	go func() {
		fmt.Println("子goroutine執(zhí)行。。。")
		time.Sleep(3 * time.Second)
		data := <-ch1 // 從通道中讀取數(shù)據(jù)
		fmt.Println("data:", data)
		done <- true
	}()
	// 向通道中寫數(shù)據(jù)。。
	time.Sleep(5 * time.Second)
	ch1 <- 100

	<-done
	fmt.Println("main。。over")

}

運行結果:

子goroutine執(zhí)行。。。
data: 100
main。。over

再舉一個例子,下面這段程序?qū)⒋蛴∫粋€數(shù)字的各位的平方和以及立方和。

package main

import (
	"fmt"
)

func calcSquares(number int, squareop chan int) {
	sum := 0
	for number != 0 {
		digit := number % 10
		sum += digit * digit
		number /= 10
	}
	squareop <- sum
}

func calcCubes(number int, cubeop chan int) {
	sum := 0
	for number != 0 {
		digit := number % 10
		sum += digit * digit * digit
		number /= 10
	}
	cubeop <- sum
}
func main() {
	number := 123
	sqrch := make(chan int)
	cubech := make(chan int)
	go calcSquares(number, sqrch)
	go calcCubes(number, cubech)
	squares, cubes := <-sqrch, <-cubech
	fmt.Println("Final output", squares, cubes)
}

運行結果:

Final output 14 36

死鎖

使用通道時要考慮的一個重要因素是死鎖。如果Goroutine在一個通道上發(fā)送數(shù)據(jù),那么預計其他的Goroutine應該接收數(shù)據(jù)。如果這種情況不發(fā)生,那么程序?qū)⒃谶\行時出現(xiàn)死鎖。

類似地,如果Goroutine正在等待從通道接收數(shù)據(jù),那么另一些Goroutine將會在該通道上寫入數(shù)據(jù),否則程序?qū)梨i。

關閉通道

發(fā)送者可以通過關閉信道,來通知接收方不會有更多的數(shù)據(jù)被發(fā)送到channel上。

close(ch)

接收者可以在接收來自通道的數(shù)據(jù)時使用額外的變量來檢查通道是否已經(jīng)關閉。

語法結構:

v, ok := <- ch  

類似map操作,存儲key,value鍵值對

v,ok := map[key] //根據(jù)key從map中獲取value,如果key存在, v就是對應的數(shù)據(jù),如果key不存在,v是默認值

在上面的語句中,如果ok的值是true,表示成功的從通道中讀取了一個數(shù)據(jù)value。如果ok是false,這意味著我們正在從一個封閉的通道讀取數(shù)據(jù)。從閉通道讀取的值將是通道類型的零值。

例如,如果通道是一個int通道,那么從封閉通道接收的值將為0。

示例代碼:

package main

import (
	"fmt"
	"time"
)

func main() {
	ch1 := make(chan int)
	go sendData(ch1)
	/*
		子goroutine,寫出數(shù)據(jù)10個
				每寫一個,阻塞一次,主程序讀取一次,解除阻塞

		主goroutine:循環(huán)讀
				每次讀取一個,堵塞一次,子程序,寫出一個,解除阻塞

		發(fā)送發(fā),關閉通道的--->接收方,接收到的數(shù)據(jù)是該類型的零值,以及false
	*/
	//主程序中獲取通道的數(shù)據(jù)
	for {
		time.Sleep(1 * time.Second)
		v, ok := <-ch1 //其他goroutine,顯示的調(diào)用close方法關閉通道。
		if !ok {
			fmt.Println("已經(jīng)讀取了所有的數(shù)據(jù),", ok, v)
			break
		}
		fmt.Println("取出數(shù)據(jù):", v, ok)
	}

	fmt.Println("main...over....")
}
func sendData(ch1 chan int) {
	// 發(fā)送方:10條數(shù)據(jù)
	for i := 0; i < 10; i++ {
		ch1 <- i //將i寫入通道中
	}
	close(ch1) //將ch1通道關閉了。
}

運行結果

取出數(shù)據(jù): 0 true
取出數(shù)據(jù): 1 true
取出數(shù)據(jù): 2 true
取出數(shù)據(jù): 3 true
取出數(shù)據(jù): 4 true
取出數(shù)據(jù): 5 true
取出數(shù)據(jù): 6 true
取出數(shù)據(jù): 7 true
取出數(shù)據(jù): 8 true
取出數(shù)據(jù): 9 true
已經(jīng)讀取了所有的數(shù)據(jù), false 0
main...over....

在上面的程序中,send Goroutine將0到9寫入chl通道,然后關閉通道。主函數(shù)里有一個無限循環(huán)。它檢查通道是否在發(fā)送數(shù)據(jù)后,使用變量ok關閉。如果ok是假的,則意味著通道關閉,因此循環(huán)結束。還可以打印接收到的值和ok的值。

通道上的范圍循環(huán)

我們可以循環(huán)從通道上獲取數(shù)據(jù),直到通道關閉。for循環(huán)的for range形式可用于從通道接收值,直到它關閉為止。

使用range循環(huán),示例代碼:

package main

import (
	"fmt"
	"time"
)

func main() {
	ch1 := make(chan int)
	go sendData(ch1)
	// for循環(huán)的for range形式可用于從通道接收值,直到它關閉為止。
	for v := range ch1 {
		fmt.Println("讀取數(shù)據(jù):", v)
	}
	fmt.Println("main..over.....")
}
func sendData(ch1 chan int) {
	for i := 0; i < 10; i++ {
		time.Sleep(1 * time.Second)
		ch1 <- i
	}
	close(ch1) //通知對方,通道關閉
}

運行結果:

讀取數(shù)據(jù): 0
讀取數(shù)據(jù): 1
讀取數(shù)據(jù): 2
讀取數(shù)據(jù): 3
讀取數(shù)據(jù): 4
讀取數(shù)據(jù): 5
讀取數(shù)據(jù): 6
讀取數(shù)據(jù): 7
讀取數(shù)據(jù): 8
讀取數(shù)據(jù): 9
main..over.....

緩沖通道

非緩沖通道

之前學習的所有通道基本上都沒有緩沖。發(fā)送和接收到一個未緩沖的通道是阻塞的。

一次發(fā)送操作對應一次接收操作,對于一個goroutine來講,它的一次發(fā)送,在另一個goroutine接收之前都是阻塞的。同樣的,對于接收來講,在另一個goroutine發(fā)送之前,它也是阻塞的。

緩沖通道

緩沖通道就是指一個通道,帶有一個緩沖區(qū)。發(fā)送到一個緩沖通道只有在緩沖區(qū)滿時才被阻塞。類似地,從緩沖通道接收的信息只有在緩沖區(qū)為空時才會被阻塞。

可以通過將額外的容量參數(shù)傳遞給make函數(shù)來創(chuàng)建緩沖通道,該函數(shù)指定緩沖區(qū)的大小。

語法:

ch := make(chan type, capacity)  

上述語法的容量應該大于0,以便通道具有緩沖區(qū)。默認情況下,無緩沖通道的容量為0,因此在之前創(chuàng)建通道時省略了容量參數(shù)。

示例代碼

以下的代碼中,chan通道,是帶有緩沖區(qū)的。

package main

import (
	"fmt"
	"strconv"
	"time"
)

func main() {
	/*
		非緩存通道:make(chan T)
		緩存通道:make(chan T ,size)
			緩存通道,理解為是隊列:

		非緩存,發(fā)送還是接受,都是阻塞的
		緩存通道,緩存區(qū)的數(shù)據(jù)滿了,才會阻塞狀態(tài)。。

	*/
	ch := make(chan string, 4)
	go sendData3(ch)
	for {
		time.Sleep(time.Second / 2)
		v, ok := <-ch
		if !ok {
			fmt.Println("讀完了,,", ok)
			break
		}
		fmt.Println("\t讀取的數(shù)據(jù)是:", v)
	}

	fmt.Println("main...over...")
}

func sendData3(ch chan string) {
	for i := 0; i < 10; i++ {
		ch <- "數(shù)據(jù)" + strconv.Itoa(i)
		fmt.Println("子goroutine,寫出第", i, "個數(shù)據(jù)")
	}
	close(ch)
}

運行結果:

子goroutine,寫出第 0 個數(shù)據(jù)
子goroutine,寫出第 1 個數(shù)據(jù)
子goroutine,寫出第 2 個數(shù)據(jù)
子goroutine,寫出第 3 個數(shù)據(jù)
	讀取的數(shù)據(jù)是: 數(shù)據(jù)0
子goroutine,寫出第 4 個數(shù)據(jù)
子goroutine,寫出第 5 個數(shù)據(jù)
	讀取的數(shù)據(jù)是: 數(shù)據(jù)1
子goroutine,寫出第 6 個數(shù)據(jù)
	讀取的數(shù)據(jù)是: 數(shù)據(jù)2
	讀取的數(shù)據(jù)是: 數(shù)據(jù)3
子goroutine,寫出第 7 個數(shù)據(jù)
	讀取的數(shù)據(jù)是: 數(shù)據(jù)4
子goroutine,寫出第 8 個數(shù)據(jù)
	讀取的數(shù)據(jù)是: 數(shù)據(jù)5
子goroutine,寫出第 9 個數(shù)據(jù)
	讀取的數(shù)據(jù)是: 數(shù)據(jù)6
	讀取的數(shù)據(jù)是: 數(shù)據(jù)7
	讀取的數(shù)據(jù)是: 數(shù)據(jù)8
	讀取的數(shù)據(jù)是: 數(shù)據(jù)9
讀完了,, false
main...over...

定向通道

雙向通道

通道,channel,是用于實現(xiàn)goroutine之間的通信的。一個goroutine可以向通道中發(fā)送數(shù)據(jù),另一條goroutine可以從該通道中獲取數(shù)據(jù)。截止到現(xiàn)在我們所學習的通道,都是既可以發(fā)送數(shù)據(jù),也可以讀取數(shù)據(jù),我們又把這種通道叫做雙向通道。

data := <- a // read from channel a  
a <- data // write to channel a
package main

import "fmt"

func main() {

	ch1 := make(chan string) // 雙向,可讀,可寫
	done := make(chan bool)
	go sendData(ch1, done)
	data := <-ch1 //阻塞
	fmt.Println("子goroutine傳來:", data)
	ch1 <- "我是main。。" // 阻塞

	<-done
	fmt.Println("main...over....")
}

// 子goroutine-->寫數(shù)據(jù)到ch1通道中
// main goroutine-->從ch1通道中取
func sendData(ch1 chan string, done chan bool) {
	ch1 <- "我是小明" // 阻塞
	data := <-ch1 // 阻塞
	fmt.Println("main goroutine傳來:", data)

	done <- true
}

運行結果:

子goroutine傳來: 我是小明
main goroutine傳來: 我是main。。
main...over....

單向通道

單向通道,也就是定向通道。

之前我們學習的通道都是雙向通道,我們可以通過這些通道接收或者發(fā)送數(shù)據(jù)。我們也可以創(chuàng)建單向通道,這些通道只能發(fā)送或者接收數(shù)據(jù)。

創(chuàng)建僅能發(fā)送數(shù)據(jù)的通道,示例代碼:

示例代碼:

package main

import "fmt"

func main()  {
	/*
		單向:定向
		chan <- T,
			只支持寫,
		<- chan T,
			只讀
	 */
	ch1 := make(chan int)//雙向,讀,寫
	//ch2 := make(chan <- int) // 單向,只寫,不能讀
	//ch3 := make(<- chan int) //單向,只讀,不能寫
	//ch1 <- 100
	//data :=<-ch1
	//ch2 <- 1000
	//data := <- ch2
	//fmt.Println(data)
	//	<-ch2 //invalid operation: <-ch2 (receive from send-only type chan<- int)
	//ch3 <- 100
	//	<-ch3
	//	ch3 <- 100 //invalid operation: ch3 <- 100 (send to receive-only type <-chan int)

	//go fun1(ch2)
	go fun1(ch1)
	data:= <- ch1
	fmt.Println("fun1中寫出的數(shù)據(jù)是:",data)

	//fun2(ch3)
	go fun2(ch1)
	ch1 <- 200
	fmt.Println("main。。over。。")
}
//該函數(shù)接收,只寫的通道
func fun1(ch chan <- int){
	// 函數(shù)內(nèi)部,對于ch只能寫數(shù)據(jù),不能讀數(shù)據(jù)
	ch <- 100
	fmt.Println("fun1函數(shù)結束。。")
}

func fun2(ch <-chan int){
	//函數(shù)內(nèi)部,對于ch只能讀數(shù)據(jù),不能寫數(shù)據(jù)
	data := <- ch
	fmt.Println("fun2函數(shù),從ch中讀取的數(shù)據(jù)是:",data)
}

運行結果:

fun1函數(shù)結束。。
fun1中寫出的數(shù)據(jù)是: 100
fun2函數(shù),從ch中讀取的數(shù)據(jù)是: 200
main。。over。。

time包中的通道相關函數(shù)

主要就是定時器,標準庫中的Timer讓用戶可以定義自己的超時邏輯,尤其是在應對select處理多個channel的超時、單channel讀寫的超時等情形時尤為方便。

Timer是一次性的時間觸發(fā)事件,這點與Ticker不同,Ticker是按一定時間間隔持續(xù)觸發(fā)時間事件。

Timer常見的創(chuàng)建方式:

t:= time.NewTimer(d)
t:= time.AfterFunc(d, f)
c:= time.After(d)

雖然說創(chuàng)建方式不同,但是原理是相同的。

Timer有3個要素:

定時時間:就是那個d
觸發(fā)動作:就是那個f
時間channel: 也就是t.C

time.NewTimer()

NewTimer()創(chuàng)建一個新的計時器,該計時器將在其通道上至少持續(xù)d之后發(fā)送當前時間。它的返回值是一個Timer。

源代碼:

// NewTimer creates a new Timer that will send
// the current time on its channel after at least duration d.
func NewTimer(d Duration) *Timer {
	c := make(chan Time, 1)
	t := &Timer{
		C: c,
		r: runtimeTimer{
			when: when(d),
			f:    sendTime,
			arg:  c,
		},
	}
	startTimer(&t.r)
	return t
}

通過源代碼我們可以看出,首先創(chuàng)建一個channel,關聯(lián)的類型為Time,然后創(chuàng)建了一個Timer并返回。

  • 用于在指定的Duration類型時間后調(diào)用函數(shù)或計算表達式。
  • 如果只是想指定時間之后執(zhí)行,使用time.Sleep()
  • 使用NewTimer(),可以返回的Timer類型在計時器到期之前,取消該計時器
  • 直到使用<-timer.C發(fā)送一個值,該計時器才會過期

示例代碼:

package main

import (
	"fmt"
	"time"
)

func main() {

	/*
		func NewTimer(d Duration) *Timer
			創(chuàng)建一個計時器:d時間以后觸發(fā),go觸發(fā)計時器的方法比較特別,就是在計時器的channel中發(fā)送值
	*/
	//新建一個計時器:timer
	timer := time.NewTimer(3 * time.Second)
	fmt.Printf("%T\n", timer) //*time.Timer
	fmt.Println(time.Now())   //2023-07-07 16:26:45.5207225 +0800 CST m=+0.001542901

	//此處在等待channel中的信號,執(zhí)行此段代碼時會阻塞3秒
	ch2 := timer.C     //<-chan time.Time
	fmt.Println(<-ch2) //2023-07-07 16:26:48.5308961 +0800 CST m=+3.011716501

}

timer.Stop

計時器停止:

示例代碼:

package main

import (
	"fmt"
	"time"
)

func main() {

	//新建計時器,一秒后觸發(fā)

	timer2 := time.NewTimer(3 * time.Second)

	//新開啟一個線程來處理觸發(fā)后的事件

	go func() {

		//等觸發(fā)時的信號

		<-timer2.C

		fmt.Println("Timer 2 結束。。")

	}()

	//由于上面的等待信號是在新線程中,所以代碼會繼續(xù)往下執(zhí)行,停掉計時器

	time.Sleep(1 * time.Second)
	stop := timer2.Stop()

	if stop {

		fmt.Println("Timer 2 停止。。")
	}
}

運行結果:

Timer 2 停止。。

time.After()

在等待持續(xù)時間之后,然后在返回的通道上發(fā)送當前時間。它相當于NewTimer(d).C。在計時器觸發(fā)之前,垃圾收集器不會恢復底層計時器。如果效率有問題,使用NewTimer代替,并調(diào)用Timer。如果不再需要計時器,請停止。

示例代碼:

package main

import (
	"fmt"
	"time"
)

func main() {

	/*
		func After(d Duration) <-chan Time
			返回一個通道:chan,存儲的是d時間間隔后的當前時間。
	*/
	ch1 := time.After(3 * time.Second) //3s后
	fmt.Printf("%T\n", ch1)            // <-chan time.Time
	fmt.Println(time.Now())            //2023-07-07 16:36:10.8553299 +0800 CST m=+0.001792901
	time2 := <-ch1
	fmt.Println(time2) //2023-07-07 16:36:13.8602885 +0800 CST m=+3.006751501

}

到了這里,關于channel通道詳解~Go進階的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【Golang】Golang進階系列教程--Go 語言數(shù)組和切片的區(qū)別

    【Golang】Golang進階系列教程--Go 語言數(shù)組和切片的區(qū)別

    在 Go 語言中,數(shù)組和切片看起來很像,但其實它們又有很多的不同之處,這篇文章就來說說它們到底有哪些不同。 數(shù)組和切片是兩個常用的數(shù)據(jù)結構。它們都可以用于存儲一組相同類型的元素,但在底層實現(xiàn)和使用方式上存在一些重要的區(qū)別。 Go 中數(shù)組的長度是不可改變的

    2024年02月15日
    瀏覽(31)
  • 【Golang】Golang進階系列教程--為什么 Go 語言 struct 要使用 tags

    【Golang】Golang進階系列教程--為什么 Go 語言 struct 要使用 tags

    在 Go 語言中,struct 是一種常見的數(shù)據(jù)類型,它可以用來表示復雜的數(shù)據(jù)結構。在 struct 中,我們可以定義多個字段,每個字段可以有不同的類型和名稱。 除了這些基本信息之外,Go 還提供了 struct tags,它可以用來指定 struct 中每個字段的元信息。 在本文中,我們將探討為什

    2024年02月15日
    瀏覽(39)
  • 【Golang】Golang進階系列教程--為什么說 Go 語言字符串是不可變的?

    【Golang】Golang進階系列教程--為什么說 Go 語言字符串是不可變的?

    最近有讀者留言說,平時在寫代碼的過程中,是會對字符串進行修改的,但網(wǎng)上都說 Go 語言字符串是不可變的,這是為什么呢? 這個問題本身并不困難,但對于新手來說確實容易產(chǎn)生困惑,今天就來回答一下。 首先來看看它的底層結構: 和切片的結構很像,只不過少了一個

    2024年02月14日
    瀏覽(98)
  • 100天精通Golang(基礎入門篇)——第15天:深入解析Go語言中函數(shù)的應用:從基礎到進階,助您精通函數(shù)編程?。ㄟM階)

    100天精通Golang(基礎入門篇)——第15天:深入解析Go語言中函數(shù)的應用:從基礎到進階,助您精通函數(shù)編程!(進階)

    ?? 博主 libin9iOak帶您 Go to Golang Language.? ?? 個人主頁——libin9iOak的博客?? ?? 《面試題大全》 文章圖文并茂??生動形象??簡單易學!歡迎大家來踩踩~?? ?? 《IDEA開發(fā)秘籍》學會IDEA常用操作,工作效率翻倍~?? ?? 希望本文能夠給您帶來一定的幫助??文章粗淺,敬請批

    2024年02月12日
    瀏覽(36)
  • Java-NIO篇章(3)——Channel通道類詳解

    Java NIO中,一個socket連接使用一個Channel(通道)來表示。對應到不同的網(wǎng)絡傳輸協(xié)議類型,在Java中都有不同的NIO Channel(通道) 相對應。其中最為重要的四種Channel(通道)實現(xiàn): FileChannel、 SocketChannel、 ServerSocketChannel、 DatagramChannel : FileChannel 文件通道,用于文件的數(shù)據(jù)讀

    2024年01月20日
    瀏覽(24)
  • 【Golang】go編程語言適合哪些項目開發(fā)?

    【Golang】go編程語言適合哪些項目開發(fā)?

    前言 在當今數(shù)字化時代,軟件開發(fā)已成為各行各業(yè)的核心需求之一。 而選擇適合的編程語言對于項目的成功開發(fā)至關重要。 本文將重點探討Go編程語言適合哪些項目開發(fā),以幫助讀者在選擇合適的編程語言時做出明智的決策。 Go 編程語言適合哪些項目開發(fā)? Go是由Google開發(fā)

    2024年02月04日
    瀏覽(29)
  • Golang開發(fā)--channel的使用

    在 Go 語言中,channel(通道)是一種用于在 goroutine 之間進行通信和同步的并發(fā)原語。它提供了一種安全且簡單的方式來傳遞數(shù)據(jù)。 1.定義通道: 通道是通過使用 make 函數(shù)來創(chuàng)建的。通道有特定的類型,用于指定通道中傳輸?shù)臄?shù)據(jù)的類型。例如,ch := make(chan int) 創(chuàng)建了一個整

    2024年02月09日
    瀏覽(22)
  • 詳解如何在Golang中監(jiān)聽多個channel

    這篇文章主要為大家詳細介紹了如何在Golang中實現(xiàn)監(jiān)聽多個channel,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下? ? 我們可以使用select來同時監(jiān)聽多個goroutine。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package main import ( ??

    2024年02月13日
    瀏覽(20)
  • Go語言中的Channel

    Channel是Go語言中一種重要的并發(fā)原語,它允許goroutine之間安全地交換數(shù)據(jù)。Channel是一個類型化的隊列,它可以存儲一個特定類型的值。goroutine可以通過發(fā)送和接收操作來向channel中寫入和讀取數(shù)據(jù)。 Channel的類型由其元素類型和容量決定。元素類型是指channel中存儲的值的類型

    2024年01月17日
    瀏覽(15)
  • Golang Channel詳解:安全并發(fā)通信與避免死鎖方法

    深入了解Golang中的Channel,探討其線程安全性、類型特性以及避免死鎖的方法。學習如何正確初始化、存取數(shù)據(jù),關閉Channel以及處理只讀只寫情況。

    2024年02月10日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包