国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

如何做網(wǎng)站的搜索欄網(wǎng)絡(luò)營銷的推廣方法有哪些

如何做網(wǎng)站的搜索欄,網(wǎng)絡(luò)營銷的推廣方法有哪些,網(wǎng)站建設(shè)lhempire,jsp網(wǎng)站建設(shè)項目實戰(zhàn)課后面向?qū)ο缶幊?Go語言的面向?qū)ο缶幊毯推渌Z言有非常大的差別。 Go 是一種面向?qū)ο蟮恼Z言嗎? 是和不是。雖然 Go 有類型和方法,并允許面向?qū)ο蟮木幊田L(fēng)格,但沒有類型層次結(jié)構(gòu)(繼承)。Go 中的“接口”概念提供了一種不…

面向?qū)ο缶幊?/h1>

Go語言的面向?qū)ο缶幊毯推渌Z言有非常大的差別。

image-20230428111344935

Go 是一種面向?qū)ο蟮恼Z言嗎?

是和不是。雖然 Go 有類型和方法,并允許面向?qū)ο蟮木幊田L(fēng)格,但沒有類型層次結(jié)構(gòu)(繼承)。Go 中的“接口”概念提供了一種不同的方法,我們認為這種方法易于使用,并且在某些方面更通用。還有一些方法可以將類型嵌入到其他類型中,以提供類似于(但不完全相同)子類化的東西。此外,Go 中的方法比 C++ 或 Java 中的方法更通用:它們可以為任何類型的數(shù)據(jù)定義,甚至是內(nèi)置類型,例如普通的“未裝箱”整數(shù)。它們不限于結(jié)構(gòu)(類)。

此外,缺少類型層次結(jié)構(gòu)使得 Go 中的“對象”感覺比 C++ 或 Java 等語言中的“對象”輕量級得多。

封裝數(shù)據(jù)和行為

結(jié)構(gòu)體定義

image-20230428121213526

實例創(chuàng)建及初始化

image-20230428121307421

type Employee struct {Id   stringName stringAge  int
}func TestCreateEmployeeObj(t *testing.T) {e := Employee{"0", "Bob", 20}e1 := Employee{Name: "Mike", Age: 30}e2 := new(Employee) // 返回指針e2.Id = "2"e2.Name = "Rose"e2.Age = 22t.Log(e)t.Log(e1)t.Log(e1.Id)t.Log(e2)t.Logf("e is %T", e)t.Logf("e2 is %T", e2)
}

image-20230428122127640

行為(方法)定義

image-20230428122402465

  • 第一種

    func (e Employee) String() string {fmt.Printf("Address is %x", unsafe.Pointer(&e.Name))fmt.Println()return fmt.Sprintf("ID:%s-Name:%s-Age:%d", e.Id, e.Name, e.Age)
    }func TestStructOperations(t *testing.T) {e := Employee{"0", "Bob", 20}fmt.Printf("Address is %x", unsafe.Pointer(&e.Name))fmt.Println()t.Log(e.String())
    }
    

    image-20230428123715323

    所以這種寫法會有復(fù)制的開銷。

  • 第二種

    func (e *Employee) String() string {fmt.Printf("Address is %x", unsafe.Pointer(&e.Name))fmt.Println()return fmt.Sprintf("ID:%s-Name:%s-Age:%d", e.Id, e.Name, e.Age)
    }func TestStructOperations(t *testing.T) {e := &Employee{"0", "Bob", 20} // 傳遞引用fmt.Printf("Address is %x", unsafe.Pointer(&e.Name))fmt.Println()t.Log(e.String())
    }
    

    image-20230428123601046

    更推薦這種。

接口(定義交互協(xié)議)

Go的接口和很多主流編程語言的接口有很大的區(qū)別。

Java代碼的示例:

image-20230428124443597

Duck Type式接口

Go語言的interface:

image-20230428125301615

type Programmer interface {WriteHelloWorld() string
}type GoProgrammer struct {
}func (g *GoProgrammer) WriteHelloWorld() string { // duck type 鴨子類型return "Hello World"
}func TestClient(t *testing.T) {var p Programmerp = new(GoProgrammer)t.Log(p.WriteHelloWorld())
}

image-20230428143644240

Go接口

image-20230428130027398

接口變量

image-20230428130325699

自定義類型

image-20230428130434903

type IntConv func(op int) int// 計算函數(shù)操作的時長
func timeSpend(inner IntConv) IntConv { // 以前的方法特別的長 我們可以用自定義類型做替換// 類似裝飾者模式,對原來的函數(shù)進行了一層包裝return func(n int) int {start := time.Now()ret := inner(n)fmt.Println("time spend:", time.Since(start).Seconds())return ret}
}

擴展和復(fù)用(類似繼承)

Go語言無法天然支持繼承,但是又想要實現(xiàn)面向?qū)ο蟮奶匦浴?/p>

即父類對象 使用子類對象初始化,那么該父類對象調(diào)用的函數(shù)就是子類實現(xiàn)的函數(shù) ,從而滿足LSP(子類交換原則)。

案例一: Go語言 支持擴展父類的功能,如下代碼:

package oriented_testimport ("fmt""testing"
)// Pet 類
type Pet struct {
}func (p *Pet) Speak(){ // Pet類的函數(shù)成員fmt.Print("Pet speak.\n")
}func (p *Pet) SpeakTo(host string) { // Pet類的函數(shù)成員p.Speak()fmt.Println("Pet SpeakTo ", host)
}// Dog 擴展Pet的功能
type Dog struct {p *Pet
}// 擴展父類的方法
func (d *Dog) Speak(){d.p.Speak()
}// 擴展父類的方法
func (d *Dog) SpeakTo(host string) {d.Speak()fmt.Println("Dog Speakto ", host)
}func TestDog(t *testing.T) {dog := new(Dog)dog.SpeakTo("Test dog")
}

以上測試代碼的輸出如下:

image-20230428141543094

dog 的 SpeakTo 中調(diào)用了 dog 的 Speak,其中調(diào)用了 Pet 的 Speak,所以輸出正常。
Pet 和 Dog 調(diào)用不會相互影響,完全由用戶決定。

但是這和我們所想需要的不同,Pet 類有自己的方法,Dog 類有自己的方法,兩者作用域完全不同。

這里Go語言推出了匿名嵌套類型,即 Dog 類不用實現(xiàn)自己的和 Pet 類同名的方法即可,通過在 Dog 類的聲明中變更 Pet 成 員。

匿名嵌套類型

案例二: Go語言支持匿名函數(shù)類型

// Dog 擴展Pet的功能
type Dog struct {Pet
}

這樣即不需要 Dog 聲明自己的同名函數(shù)成員,默認的調(diào)用即為 Pet 成員函數(shù)的調(diào)用。

package oriented_testimport ("fmt""testing"
)type Pet struct {
}func (p *Pet) Speak(){fmt.Print("Pet speak.\n")
}func (p *Pet) SpeakTo(host string) {p.Speak()fmt.Println("Pet SpeakTo ", host)
}// Dog 擴展Pet的功能
type Dog struct {Pet // 支持匿名嵌套類型
}func TestDog(t *testing.T) {var dog Dogdog.Speak()dog.SpeakTo("Test dog")
}

最終的輸出如下:

image-20230428141503654

調(diào)用的都是 Pet 的成員函數(shù),感覺像是繼承了,因為繼承默認就是子類能夠使用父類的公有成員。

在匿名嵌套類型下,我們想要完整嘗試一下Go語言是否真正支持繼承,可以像之前的代碼一樣在 Dog 中實現(xiàn) Pet 的同名函數(shù),且能夠通過父類對象調(diào)用子類的成員方法,像 C++/Java 這樣進行向上類型轉(zhuǎn)換(本身是不可能的,Go語言不支持顯式類型轉(zhuǎn)換)。

案例三: Go語言不支持繼承,如下代碼:

package oriented_testimport ("fmt""testing"
)type Pet struct {
}func (p *Pet) Speak(){fmt.Print("Pet speak.\n")
}func (p *Pet) SpeakTo(host string) {p.Speak()fmt.Println("Pet SpeakTo ", host)
}// Dog 擴展Pet的功能
type Dog struct {//p *PetPet // 支持匿名嵌套類型
}// 重載父類的方法
func (d *Dog) Speak(){fmt.Print("Dog speak.\n")
}// 重載父類的方法
func (d *Dog) SpeakTo(host string) {d.Speak()fmt.Println("Dog Speakto ", host)
}func TestDog(t *testing.T) {var dog Pet = new(Dog) // 這里就會編譯錯誤dog.Speak()dog.SpeakTo("Test dog")
}
cannot use new(Dog) (value of type *Dog) as Pet value in variable declaration
不支持將Pet類型轉(zhuǎn)換為Dog類型

總結(jié)一下,Go語言并不支持繼承,能夠支持接口的擴展 和 復(fù)用**(匿名嵌套類型)**,內(nèi)嵌這種方式是完全不能當成繼承來用的,因為它不支持訪問子類的方法數(shù)據(jù)(重載),不支持LSP原則。

其中擴展 就是不同類實現(xiàn)相同的成員函數(shù),能夠?qū)崿F(xiàn)類似于案例一中的擴展接口形態(tài)。

復(fù)用則是通過匿名嵌套類型實現(xiàn) 類似于重載的功能,可以看看案例二的代碼。

多態(tài)

image-20230428143317910

type Programmer interface {WriteHelloWorld() string
}type GoProgrammer struct {
}func (g *GoProgrammer) WriteHelloWorld() string {return "fmt.Println(\"Hello World\")"
}type JavaProgrammer struct {
}func (j *JavaProgrammer) WriteHelloWorld() string {return "System.out.println(\"Hello World\")"
}// 多態(tài)
func writeFirstProgram(p Programmer) {fmt.Printf("%T %v\n", p, p.WriteHelloWorld())
}func TestClient(t *testing.T) {goProgrammer := new(GoProgrammer)javaProgrammer := new(JavaProgrammer)writeFirstProgram(goProgrammer)writeFirstProgram(javaProgrammer)
}

image-20230428144147613

空接口與斷言

image-20230428144326958

func DoSomething(p interface{}) {// '.' 斷言,p.(int),p斷言為int類型if i, ok := p.(int); ok {fmt.Println("Integer", i)return}if s, ok := p.(string); ok {fmt.Println("string", s)return}fmt.Println("UnKnow type")
}func TestEmptyInterface(t *testing.T) {DoSomething(10)DoSomething("10")DoSomething(10.00)
}

image-20230428145558309

Go接口最佳實踐

image-20230428145718339

錯誤機制

error

image-20230428150518369

package errorimport ("errors""testing"
)func GetFibonacci(n int) ([]int, error) {if n < 2 || n > 100 {return nil, errors.New("n should be in [2, 100]")}fibList := []int{1, 1}for i := 2; i < n; i++ {fibList = append(fibList, fibList[i-1]+fibList[i-2])}return fibList, nil
}func TestGetFibonacci(t *testing.T) {if v, err := GetFibonacci(-10); err != nil {t.Error(err)} else {t.Log(v)}
}

image-20230428161919642

最佳實踐

image-20230428162534768

盡早失敗,避免嵌套!

例:

func GetFibonacci2(str string) {var (i    interr  errorlist []int)if i, err = strconv.Atoi(str); err != nil {fmt.Println("Error", err)return}if list, err = GetFibonacci(i); err != nil {fmt.Println("Error", err)return}fmt.Println(list)
}

panic

image-20230428163230055

panic vs os.Exit

image-20230428163307433

revocer

image-20230428164252392

recover 類似于 java 的 catch。

func TestRecover(t *testing.T) {defer func() {if err := recover(); err != nil {fmt.Println("recovered from", err)}}()fmt.Println("Start")panic(errors.New("something wrong"))
}

image-20230428183030584

image-20230428165703129

其實上面這種修復(fù)方式是非常危險的。

我們一定要當心自己 revocer 在做的事,因為我們 revocer 并不檢測到底發(fā)生了什么錯誤,而只是記錄了一下或者直接忽略掉了,這時可能系統(tǒng)某些核心資源消耗完了,但我們把他強制恢復(fù)之后系統(tǒng)依然是不能正常工作的,還會導(dǎo)致我們的健康檢查程序 health check 檢查不出當前系統(tǒng)的問題,因為很多 health check 只是檢查當前系統(tǒng)的進程在還是不在, 因為我們的進程是在的,所以就會形成僵尸進程,它還活著,但它不能提供服務(wù)。

image-20230428165726627

如果出現(xiàn)了這種問題,我們可以用 “Let is Crash” 可恢復(fù)的設(shè)計模式,我們直接 crash 掉,這樣守護進程就會重新把服務(wù)進程提起來(說的有點高大上,其實就是重啟),重啟是恢復(fù)不確定性錯誤的最好方法。

包 package

構(gòu)建可復(fù)用的模塊(包)

image-20230428183701611

image-20230428185412938

my_series.go

package seriesfunc GetFibonacci(n int) ([]int, error) {ret := []int{1, 1}for i := 2; i < n; i++ {ret = append(ret, ret[i-1]+ret[i-2])}return ret, nil
}

package_test.go

引用另一個包中的方法:

package clientimport ("mygoland/geekvideo/ch13/series" // 包路徑要從自己的gopath開始寫起"testing"
)func TestPackage(t *testing.T) {t.Log(series.GetFibonacci(10))
}

init方法

image-20230428185555174

func init() {fmt.Println("init1")
}func init() {fmt.Println("init2")
}func GetFibonacci(n int) []int {ret := []int{1, 1}for i := 2; i < n; i++ {ret = append(ret, ret[i-1]+ret[i-2])}return ret
}

image-20230428185810992

如何使用遠程的package

image-20230428192434197

ConcurrentMap for GO

https://github.com/easierway/concurrent_map

使用 go get 命令導(dǎo)入

go get -u github.com/easierway/concurrent_map

image-20230428192052651

package remoteimport (cm "github.com/easierway/concurrent_map" // 導(dǎo)入遠程包"testing"
)func TestConcurrentMap(t *testing.T) {m := cm.CreateConcurrentMap(99)m.Set(cm.StrKey("key"), 10)t.Log(m.Get(cm.StrKey("key")))
}

image-20230428192409198

依賴管理

Go未解決的依賴問題

image-20230429184940847

vendor路徑

image-20230429185019589

常用的依賴管理工具

  • godep:https://github.com/tools/godep
  • glide:https://github.com/Masterminds/glide
  • dep:https://github.com/golang/dep

安裝glide

  • mac環(huán)境,使用 brew 安裝 glide

    brew install glide
    

    安裝成功
    image-20230430132905106

  • 初始化 glide

    glide init
    

    image-20230505090852387

    image-20230505092905006

    image-20230505093034649

    image-20230505093114018

    image-20230505093146424

    image-20230505093229266

    image-20230505093327934

  • glide init 執(zhí)行完畢后,生成了一個 yaml 文件,并把依賴的包和版本號定義在了里面

    image-20230505093453057

  • 在之前的目錄下執(zhí)行glide install

    image-20230505094627270

    然后就會在我們的指定的文件下面生成一個 vender 目錄和 glide.lock 文件。

    image-20230505094650525

  • 到此為止,Go 就能 搜索到 vender 目錄下面的 package 了,我們就通過 vender 來指定了包的路徑和版本號,即實現(xiàn)了在同一環(huán)境下使用同一個包的不同版本依賴了。

筆記整理自極客時間視頻教程:Go語言從入門到實戰(zhàn)

http://aloenet.com.cn/news/41108.html

相關(guān)文章:

  • 自己搭建服務(wù)器做網(wǎng)站91手機用哪個瀏覽器
  • 網(wǎng)站優(yōu)化主旨百度廣告推廣收費標準
  • 武漢專業(yè)網(wǎng)站建設(shè)zz51上海網(wǎng)站制作開發(fā)
  • 競網(wǎng)做的網(wǎng)站交換鏈接營銷成功案例
  • 做網(wǎng)站與考研學(xué)技術(shù)包分配的培訓(xùn)機構(gòu)
  • WordPress方糖無錫網(wǎng)站建設(shè)優(yōu)化公司
  • 專業(yè)的團隊網(wǎng)站建設(shè)引擎搜索入口
  • 室內(nèi)裝修設(shè)計圖紙seo快速軟件
  • 外國人做外貿(mào)都會瀏覽哪些網(wǎng)站焊工培訓(xùn)內(nèi)容有哪些
  • 網(wǎng)站建設(shè)常用代碼營銷策劃36計
  • 直播視頻網(wǎng)站如何做網(wǎng)站策劃
  • 佛山專業(yè)做企業(yè)網(wǎng)站上海今天最新發(fā)布會
  • 吉 360 網(wǎng)站建設(shè)如何做好精準營銷
  • 網(wǎng)站客服工作內(nèi)容重慶網(wǎng)站建設(shè)哪家好
  • 凡客專賣店網(wǎng)站優(yōu)化入門
  • 安徽國貿(mào)集團網(wǎng)站建設(shè)沈陽網(wǎng)站推廣優(yōu)化
  • 合肥專業(yè)做網(wǎng)站的互聯(lián)網(wǎng)域名注冊查詢
  • 做網(wǎng)站拍攝照片用什么佳能相機好網(wǎng)站優(yōu)化課程培訓(xùn)
  • 哪個網(wǎng)站可以做社工試題網(wǎng)絡(luò)服務(wù)器
  • 湖北住房和城鄉(xiāng)建設(shè)委員會網(wǎng)站東莞市民最新疫情
  • 三門峽集團網(wǎng)站建設(shè)愛站網(wǎng)關(guān)鍵詞查詢工具
  • 有沒有人與動物做的電影網(wǎng)站自己做網(wǎng)站怎么做
  • 自適應(yīng)全屏網(wǎng)站競價排名名詞解釋
  • 網(wǎng)站建設(shè)網(wǎng)站排名優(yōu)化金牌服務(wù)搜索引擎排名影響因素有哪些
  • 房屋網(wǎng)簽查詢系統(tǒng)官方網(wǎng)站知乎推廣
  • 個人網(wǎng)站怎么做推廣好口碑關(guān)鍵詞優(yōu)化
  • 深圳市網(wǎng)站維護seo短視頻網(wǎng)頁入口
  • 營銷公關(guān)seo關(guān)鍵詞找29火星軟件
  • wordpress博客實戰(zhàn)青島百度整站優(yōu)化服務(wù)
  • 網(wǎng)站圖文列表seo優(yōu)化快排