亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go基礎(chǔ)教程系列之Go接口使用詳解

 更新時(shí)間:2022年04月16日 17:16:19   作者:駿馬金龍  
這篇文章主要介紹了Go基礎(chǔ)教程系列之Go接口使用詳解,需要的朋友可以參考下

接口用法簡(jiǎn)介

接口(interface)是一種類(lèi)型,用來(lái)定義行為(方法)。

type Namer interface {
    my_method1()
    my_method2(para)
    my_method3(para) return_type
    ...
}

但這些行為不會(huì)在接口上直接實(shí)現(xiàn),而是需要用戶(hù)自定義的方法來(lái)實(shí)現(xiàn)。所以,在上面的Namer接口類(lèi)型中的方法my_methodN都是沒(méi)有實(shí)際方法體的,僅僅只是在接口Namer中存放這些方法的簽名(簽名 = 函數(shù)名+參數(shù)(類(lèi)型)+返回值(類(lèi)型))。

當(dāng)用戶(hù)自定義的類(lèi)型實(shí)現(xiàn)了接口上定義的這些方法,那么自定義類(lèi)型的值(也就是實(shí)例)可以賦值給接口類(lèi)型的值(也就是接口實(shí)例)。這個(gè)賦值過(guò)程使得接口實(shí)例中保存了用戶(hù)自定義類(lèi)型實(shí)例。

例如:

package main

import (
	"fmt"
)

// Shaper 接口類(lèi)型
type Shaper interface {
	Area() float64
}

// Circle struct類(lèi)型
type Circle struct {
	radius float64
}

// Circle類(lèi)型實(shí)現(xiàn)Shaper中的方法Area()
func (c *Circle) Area() float64 {
	return 3.14 * c.radius * c.radius
}

// Square struct類(lèi)型
type Square struct {
	length float64
}

// Square類(lèi)型實(shí)現(xiàn)Shaper中的方法Area()
func (s *Square) Area() float64 {
	return s.length * s.length
}

func main() {
	// Circle類(lèi)型的指針類(lèi)型實(shí)例
	c := new(Circle)
	c.radius = 2.5

	// Square類(lèi)型的值類(lèi)型實(shí)例
	s := Square{3.2}

	// Sharpe接口實(shí)例ins1,它自身是指針類(lèi)型的
	var ins1 Shaper
	// 將Circle實(shí)例c賦值給接口實(shí)例ins1
	// 那么ins1中就保存了實(shí)例c
	ins1 = c
	fmt.Println(ins1)

	// 使用類(lèi)型推斷將Square實(shí)例s賦值給接口實(shí)例
	ins2 := s
	fmt.Println(ins2)
}

上面將輸出:

&{2.5}
{3.2}

從上面輸出結(jié)果中可以看出,兩個(gè)接口實(shí)例ins1和ins2被分別賦值后,分別保存了指針類(lèi)型的Circle實(shí)例c和值類(lèi)型的Square實(shí)例s

另外,從上面賦值ins1和ins2的賦值語(yǔ)句上看:

ins1 = c
ins2 := s

是否說(shuō)明接口實(shí)例ins就是自定義類(lèi)型的實(shí)例?實(shí)際上接口是指針類(lèi)型(指向什么見(jiàn)下文)。這個(gè)時(shí)候,自定義類(lèi)型的實(shí)例c、s稱(chēng)為具體實(shí)例,ins實(shí)例是抽象實(shí)例,因?yàn)閕ns接口中定義的行為(方法)并沒(méi)有具體的行為模式,而c、s中的行為是具體的。

因?yàn)榻涌趯?shí)例ins也是自定義類(lèi)型的實(shí)例,所以當(dāng)接口實(shí)例中保存了自定義類(lèi)型的實(shí)例后,就可以直接從接口上調(diào)用它所保存的實(shí)例的方法。例如:

fmt.Println(ins1.Area())   // 輸出19.625
fmt.Println(ins2.Area())   // 輸出10.24

這里ins1.Area()調(diào)用的是Circle類(lèi)型上的方法Area(),ins2.Area()調(diào)用的則是Square類(lèi)型上的方法Area()。這說(shuō)明Go的接口可以實(shí)現(xiàn)面向?qū)ο笾械亩鄳B(tài):可以按需調(diào)用名稱(chēng)相同、功能不同的方法

接口實(shí)例中存的是什么

前面說(shuō)了,接口類(lèi)型是指針類(lèi)型,但是它到底存放了什么東西?

接口類(lèi)型的數(shù)據(jù)結(jié)構(gòu)是2個(gè)指針,占用2個(gè)機(jī)器字長(zhǎng)。

當(dāng)將類(lèi)型實(shí)例c賦值給接口實(shí)例ins1后,用println()函數(shù)輸出ins1和c,比較它們的地址:

println(ins1)
println(c)

輸出結(jié)果:

(0x4ceb00,0xc042068058)
0xc042068058

從結(jié)果中可以看出,接口實(shí)例中包含了兩個(gè)地址,其中第二個(gè)地址和類(lèi)型實(shí)例c的地址是完全相同的。而第二個(gè)地址c是Circle的指針類(lèi)型實(shí)例,所以ins中的第二個(gè)值也是指針。

ins中的第一個(gè)是指針是什么?它所指向的是一個(gè)內(nèi)部表結(jié)構(gòu)iTable,這個(gè)Table中包含兩部分:第一部分是實(shí)例c的類(lèi)型信息,也就是*Circle,第二部分是這個(gè)類(lèi)型(Circle)的方法集,也就是Circle類(lèi)型的所有方法(此示例中Circle只定義了一個(gè)方法Area())。

所以,如圖所示:

注意,上圖中的實(shí)例c是指針,是指針類(lèi)型的Circle實(shí)例。

對(duì)于值類(lèi)型的Square實(shí)例s,ins2保存的內(nèi)容則如下圖:

實(shí)際上接口實(shí)例中保存的內(nèi)容,在反射(reflect)中體現(xiàn)的淋漓盡致,reflect所有的一切都離不開(kāi)接口實(shí)例保存的內(nèi)容。

方法集(Method Set)規(guī)則

官方手冊(cè)對(duì)Method Set的解釋?zhuān)?a rel="external nofollow" target="_blank">https://golang.org/ref/spec#Method_sets

實(shí)例的method set決定了它所實(shí)現(xiàn)的接口,以及通過(guò)receiver可以調(diào)用的方法。

方法集是類(lèi)型的方法集合,對(duì)于非接口類(lèi)型,每個(gè)類(lèi)型都分兩個(gè)Method Set:值類(lèi)型實(shí)例是一個(gè)Method Set,指針類(lèi)型的實(shí)例是另一個(gè)Method Set。兩個(gè)Method Set由不同receiver類(lèi)型的方法組成:

實(shí)例的類(lèi)型       receiver
--------------------------------------
 值類(lèi)型:T       (T Type)
 指針類(lèi)型:*T    (T Type)或(T *Type)

也就是說(shuō):

  • 值類(lèi)型的實(shí)例的Method Set只由值類(lèi)型的receiver(T Type)組成
  • 指針類(lèi)型的實(shí)例的Method Set由值類(lèi)型和指針類(lèi)型的receiver共同組成,即(T Type)(T *Type)

這是什么意思呢?從receiver的角度去考慮:

receiver        實(shí)例的類(lèi)型
---------------------------
(T Type)        T 或 *T
(T *Type)       *T

上面的意思是:

  • receiver是指針類(lèi)型的方法只可能存在于指針類(lèi)型的實(shí)例方法集中
  • receiver是值類(lèi)型的方法既存在于值類(lèi)型的實(shí)例方法集中,也存在于指針類(lèi)型的方法集中

從實(shí)現(xiàn)接口方法的角度上看:

  • 如果某類(lèi)型實(shí)現(xiàn)接口的方法的receiver是(T *Type)類(lèi)型的,那么只有指針類(lèi)型的實(shí)例*T才算是實(shí)現(xiàn)了這個(gè)接口,因?yàn)檫@個(gè)方法不在值類(lèi)型的實(shí)例T方法集中
  • 如果某類(lèi)型實(shí)現(xiàn)接口的方法的receiver是(T Type)類(lèi)型的,那么值類(lèi)型的實(shí)例T和指針類(lèi)型的實(shí)例*T都算實(shí)現(xiàn)了這個(gè)接口,因?yàn)檫@個(gè)方法既在值類(lèi)型的實(shí)例T方法集中,也在指針類(lèi)型的實(shí)例*T方法集中

舉個(gè)例子。接口方法Area(),自定義類(lèi)型Circle有一個(gè)receiver類(lèi)型為(c *Circle)的Area()方法時(shí),說(shuō)明實(shí)現(xiàn)了接口的方法,但只有Circle實(shí)例的類(lèi)型為指針類(lèi)型時(shí),這個(gè)實(shí)例才算是實(shí)現(xiàn)了接口,才能賦值給接口實(shí)例,才能當(dāng)作一個(gè)接口參數(shù)。如下:

package main

import "fmt"

// Shaper 接口類(lèi)型
type Shaper interface {
	Area() float64
}

// Circle struct類(lèi)型
type Circle struct {
	radius float64
}

// Circle類(lèi)型實(shí)現(xiàn)Shaper中的方法Area()
// receiver類(lèi)型為指針類(lèi)型
func (c *Circle) Area() float64 {
	return 3.14 * c.radius * c.radius
}

func main() {
	// 聲明2個(gè)接口實(shí)例
	var ins1, ins2 Shaper

	// Circle的指針類(lèi)型實(shí)例
	c1 := new(Circle)
	c1.radius = 2.5
	ins1 = c1
	fmt.Println(ins1.Area())

	// Circle的值類(lèi)型實(shí)例
	c2 := Circle{3.0}
	// 下面的將報(bào)錯(cuò)
	ins2 = c2
	fmt.Println(ins2.Area())
}

報(bào)錯(cuò)結(jié)果:

cannot use c2 (type Circle) as type Shaper
in assignment:
        Circle does not implement Shaper (Area method has
pointer receiver)

它的意思是,Circle值類(lèi)型的實(shí)例c2沒(méi)有實(shí)現(xiàn)Share接口的Area()方法,它的Area()方法是指針類(lèi)型的receiver。換句話(huà)說(shuō),值類(lèi)型的c2實(shí)例的Method Set中沒(méi)有receiver類(lèi)型為指針的Area()方法。

所以,上面應(yīng)該改成:

ins2 = &c2

再聲明一個(gè)方法,它的receiver是值類(lèi)型的。下面的代碼一切正常。

type Square struct{
    length float64
}

// 實(shí)現(xiàn)方法Area(),receiver為值類(lèi)型
func (s Square) Area() float64{
    return s.length * s.length
}

func main() {
    var ins3,ins4 Shaper

    // 值類(lèi)型的Square實(shí)例s1
    s1 := Square{3.0}
    ins3 = s1
    fmt.Println(ins3.Area())

    // 指針類(lèi)型的Square實(shí)例s2
    s2 := new(Square)
    s2.length=4.0
    ins4 = s2
    fmt.Println(ins4.Area())
}

所以,從struct類(lèi)型定義的方法的角度去看,如果這個(gè)類(lèi)型的方法有指針類(lèi)型的receiver方法,則只能使用指針類(lèi)型的實(shí)例賦值給接口變量,才算是實(shí)現(xiàn)了接口。如果這個(gè)類(lèi)型的方法全是值類(lèi)型的receiver方法,則可以隨意使用值類(lèi)型或指針類(lèi)型的實(shí)例賦值給接口變量。下面這兩個(gè)對(duì)應(yīng)關(guān)系,對(duì)于理解很有幫助:

實(shí)例的類(lèi)型       receiver
--------------------------------------
 值類(lèi)型:T       (T Type)
 指針類(lèi)型:*T    (T Type)或(T *Type)
 
receiver        實(shí)例的類(lèi)型
---------------------------
(T Type)        T 或 *T
(T *Type)       *T

很經(jīng)常的,我們會(huì)直接使用推斷類(lèi)型的賦值方式(如ins2 := c2)將實(shí)例賦值給一個(gè)變量,我們以為這個(gè)變量是接口的實(shí)例,但實(shí)際上并不一定。正如上面值類(lèi)型的c2賦值給ins2,這個(gè)ins2將是從c2數(shù)據(jù)結(jié)構(gòu)拷貝而來(lái)的另一個(gè)副本數(shù)據(jù)結(jié)構(gòu),并非接口實(shí)例,但這時(shí)通過(guò)ins2也能調(diào)用Area()方法:

c2 = Circle{3.2}
ins2 := c2
fmt.Println(ins2.Area())  // 正常執(zhí)行

之所以能調(diào)用,是因?yàn)镃ircle類(lèi)型中有Area()方法,但這不是通過(guò)接口去調(diào)用的。

所以,在使用接口的時(shí)候,應(yīng)當(dāng)盡量使用var先聲明接口類(lèi)型的實(shí)例,再將類(lèi)型的實(shí)例賦值給接口實(shí)例(如var ins1,ins2 Shaper),或者使用ins1 := Shaper(c1)的方式。這樣,如果賦值給接口實(shí)例的類(lèi)型實(shí)例沒(méi)有實(shí)現(xiàn)該接口,將會(huì)報(bào)錯(cuò)。

但是,為什么要限制指針類(lèi)型的receiver只能是指針類(lèi)型的實(shí)例的Method Set呢?

看下圖,假如指針類(lèi)型的receiver可以組成值類(lèi)型實(shí)例的Method Set,那么接口實(shí)例的第二個(gè)指針就必須找到值類(lèi)型的實(shí)例的地址。但實(shí)際上,并非所有值類(lèi)型的實(shí)例都能獲取到它們的地址。

哪些值類(lèi)型的實(shí)例找不到地址?最常見(jiàn)的是那些簡(jiǎn)單數(shù)據(jù)類(lèi)型的別名類(lèi)型,如果匿名生成它們的實(shí)例,它們的地址就會(huì)被Go徹底隱藏,外界找不到這個(gè)實(shí)例的地址。

例如:

package main

import "fmt"

type myint int

func (m *myint) add() myint {
	return *m + 1
}
func main() {
	fmt.Println(myint(3).add())
}

以下是報(bào)錯(cuò)信息:找不到myint(3)的地址

abc\abc.go:11:22: cannot call pointer method on myint(3)
abc\abc.go:11:22: cannot take the address of myint(3)

這里的myint(3)是匿名的myint實(shí)例,它的底層是簡(jiǎn)單數(shù)據(jù)類(lèi)型int,myint(3)的地址會(huì)被徹底隱藏,只會(huì)提供它的值對(duì)象3。

普通方法和實(shí)現(xiàn)接口方法的區(qū)別

對(duì)于普通方法,無(wú)論是值類(lèi)型還是指針類(lèi)型的實(shí)例,都能正常調(diào)用,且調(diào)用時(shí)拷貝的內(nèi)容都由receiver的類(lèi)型決定。

func (T Type) method1   // 值類(lèi)型receiver
func (T *Type) method2  // 指針類(lèi)型receiver

指針類(lèi)型的receiver決定了無(wú)論是值類(lèi)型還是指針類(lèi)型的實(shí)例,都拷貝實(shí)例的指針。值類(lèi)型的receiver決定了無(wú)論是值類(lèi)型還是指針類(lèi)型的實(shí)例,都拷貝實(shí)例本身。

所以,對(duì)于person數(shù)據(jù)結(jié)構(gòu):

type person struct {}
p1 := person{}       // 值類(lèi)型的實(shí)例
p2 := new(person)    // 指針類(lèi)型的實(shí)例

p1.method1()p2.method1()都是拷貝整個(gè)person實(shí)例,只不過(guò)Go對(duì)待p2.method1()時(shí)多一個(gè)"步驟":將其解除引用。所以p2.method1()等價(jià)于(*p2).method1()。

p1.method2()p2.method2()都拷貝person實(shí)例的指針,只不過(guò)Go對(duì)待p1.method2()時(shí)多一個(gè)"步驟":創(chuàng)建一個(gè)額外的引用。所以,p1.method2()等價(jià)于(&p1).method2()。

而類(lèi)型實(shí)現(xiàn)接口方法時(shí),method set規(guī)則決定了類(lèi)型實(shí)例是否實(shí)現(xiàn)了接口。

receiver        實(shí)例的類(lèi)型
---------------------------
(T Type)        T 或 *T
(T *Type)       *T

對(duì)于接口abc、接口方法method1()、method2()和結(jié)構(gòu)person:

type abc interface {
	method1
	method2
}

type person struct {}
func (T person) method1   // 值類(lèi)型receiver
func (T *person) method2  // 指針類(lèi)型receiver

p1 := abc(person)  // 接口變量保存值類(lèi)型實(shí)例
p2 := abc(&person) // 接口變量保存指針類(lèi)型實(shí)例

p2.method1()、p2.method2()以及p1.method1()都是允許的,都會(huì)通過(guò)接口實(shí)例去調(diào)用具體person實(shí)例的方法。

p1.method2()是錯(cuò)誤的,因?yàn)閙ethod2()的receiver是指針類(lèi)型的,導(dǎo)致p1沒(méi)有實(shí)現(xiàn)接口abc的method2()方法。

接口類(lèi)型作為參數(shù)

將接口類(lèi)型作為參數(shù)很常見(jiàn)。這時(shí),那些實(shí)現(xiàn)接口的實(shí)例都能作為接口類(lèi)型參數(shù)傳遞給函數(shù)/方法。

例如,下面的myArea()函數(shù)的參數(shù)是n Shaper,是接口類(lèi)型。

package main

import (
	"fmt"
)

// Shaper 接口類(lèi)型
type Shaper interface {
	Area() float64
}

// Circle struct類(lèi)型
type Circle struct {
	radius float64
}

// Circle類(lèi)型實(shí)現(xiàn)Shaper中的方法Area()
func (c *Circle) Area() float64 {
	return 3.14 * c.radius * c.radius
}

func main() {
	// Circle的指針類(lèi)型實(shí)例
	c1 := new(Circle)
	c1.radius = 2.5
	myArea(c1)
}

func myArea(n Shaper) {
	fmt.Println(n.Area())
}

上面myArea(c1)是將c1作為接口類(lèi)型參數(shù)傳遞給n,然后調(diào)用c1.Area(),因?yàn)閷?shí)現(xiàn)了接口方法,所以調(diào)用的是Circle的Area()。

如果實(shí)現(xiàn)接口方法的receiver是指針類(lèi)型的,但卻是值類(lèi)型的實(shí)例,將沒(méi)法作為接口參數(shù)傳遞給函數(shù),原因前面已經(jīng)解釋過(guò)了,這種類(lèi)型的實(shí)例沒(méi)有實(shí)現(xiàn)接口。

以接口作為方法或函數(shù)的參數(shù),將使得一切都變得靈活且通用,只要是實(shí)現(xiàn)了接口的類(lèi)型實(shí)例,都可以去調(diào)用它。

用的非常多的fmt.Println(),它的參數(shù)也是接口,而且是變長(zhǎng)的接口參數(shù):

$ go doc fmt Println
func Println(a ...interface{}) (n int, err error)

每一個(gè)參數(shù)都會(huì)放進(jìn)一個(gè)名為a的Slice中,Slice中的元素是接口類(lèi)型,而且是空接口,這使得無(wú)需實(shí)現(xiàn)任何方法,任何東西都可以丟到fmt.Println()中來(lái),至于每個(gè)東西怎么輸出,那就要看具體情況:由類(lèi)型的實(shí)現(xiàn)的String()方法決定。

接口類(lèi)型的嵌套

接口可以嵌套,嵌套的內(nèi)部接口將屬于外部接口,內(nèi)部接口的方法也將屬于外部接口。

例如,F(xiàn)ile接口內(nèi)部嵌套了ReadWrite接口和Lock接口。

type ReadWrite interface {
    Read(b Buffer) bool
    Write(b Buffer) bool
}
type Lock interface {
    Lock()
    Unlock()
}
type File interface {
    ReadWrite
    Lock
    Close()
}

除此之外,類(lèi)型嵌套時(shí),如果內(nèi)部類(lèi)型實(shí)現(xiàn)了接口,那么外部類(lèi)型也會(huì)自動(dòng)實(shí)現(xiàn)接口,因?yàn)閮?nèi)部屬性是屬于外部屬性的。

更多關(guān)于Go基礎(chǔ)教程系列之Go接口的使用方法請(qǐng)查看下面的相關(guān)鏈接

相關(guān)文章

  • 通過(guò)Golang編寫(xiě)一個(gè)AES加密解密工具

    通過(guò)Golang編寫(xiě)一個(gè)AES加密解密工具

    這篇文章主要為大家詳細(xì)介紹了如何利用Golang制作一個(gè)AES加密解密工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-05-05
  • golang求連續(xù)子數(shù)組的最大和實(shí)例

    golang求連續(xù)子數(shù)組的最大和實(shí)例

    這篇文章主要介紹了golang求連續(xù)子數(shù)組的最大和實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • golang?手寫(xiě)貪吃蛇示例實(shí)現(xiàn)

    golang?手寫(xiě)貪吃蛇示例實(shí)現(xiàn)

    這篇文章主要為大家介紹了golang?手寫(xiě)貪吃蛇示例實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • golang?recover函數(shù)使用中的一些坑解析

    golang?recover函數(shù)使用中的一些坑解析

    這篇文章主要為大家介紹了golang?recover函數(shù)使用中的一些坑解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • go語(yǔ)言中os包的用法實(shí)戰(zhàn)大全

    go語(yǔ)言中os包的用法實(shí)戰(zhàn)大全

    Go在os中提供了文件的基本操作,包括通常意義的打開(kāi)、創(chuàng)建、讀寫(xiě)等操作,除此以外為了追求便捷以及性能上,Go還在io/ioutil以及bufio提供一些其他函數(shù)供開(kāi)發(fā)者使用,這篇文章主要給大家介紹了關(guān)于go語(yǔ)言中os包用法的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • 解決Golang time.Parse和time.Format的時(shí)區(qū)問(wèn)題

    解決Golang time.Parse和time.Format的時(shí)區(qū)問(wèn)題

    這篇文章主要介紹了解決Golang time.Parse和time.Format的時(shí)區(qū)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • golang time包的用法詳解

    golang time包的用法詳解

    這篇文章主要介紹了golang time包的用法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Go打包附件內(nèi)容到執(zhí)行文件的方法

    Go打包附件內(nèi)容到執(zhí)行文件的方法

    處于種種原因, 我們不希望這部分額外的內(nèi)容以附件的形式出現(xiàn), 有沒(méi)有什么辦法能夠?qū)⒏郊?nèi)容直接打包進(jìn)可執(zhí)行文件中呢,下面小編給大家介紹下Go打包附件內(nèi)容到執(zhí)行文件的方法,感興趣的朋友一起看看吧
    2023-03-03
  • Golang內(nèi)存分配機(jī)制詳解

    Golang內(nèi)存分配機(jī)制詳解

    Go 語(yǔ)言的內(nèi)存分配機(jī)制是理解和優(yōu)化 Go 程序性能的關(guān)鍵,在 Go 中,內(nèi)存管理是自動(dòng)進(jìn)行的,這得益于 Go 的垃圾回收機(jī)制,了解內(nèi)存如何分配和回收,可以幫助我們寫(xiě)出更高性能的代碼,本文將深入講解下 Go 內(nèi)存分配機(jī)制,需要的朋友可以參考下
    2023-12-12
  • Golang監(jiān)聽(tīng)日志文件并發(fā)送到kafka中

    Golang監(jiān)聽(tīng)日志文件并發(fā)送到kafka中

    這篇文章主要介紹了Golang監(jiān)聽(tīng)日志文件并發(fā)送到kafka中,日志收集項(xiàng)目的準(zhǔn)備中,本文主要講的是利用golang的tail庫(kù),監(jiān)聽(tīng)日志文件的變動(dòng),將日志信息發(fā)送到kafka中?,需要的朋友可以參考一下
    2022-04-04

最新評(píng)論