第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 Go 中實(shí)現(xiàn)抽象類?

如何在 Go 中實(shí)現(xiàn)抽象類?

Go
慕妹3242003 2021-10-04 18:12:03
如何在 Go 中實(shí)現(xiàn)抽象類?由于 Go 不允許我們在接口中有字段,這將是一個無狀態(tài)對象。那么,換句話說,是否有可能為 Go 中的方法提供某種默認(rèn)實(shí)現(xiàn)?考慮一個例子:type Daemon interface {    start(time.Duration)    doWork()}func (daemon *Daemon) start(duration time.Duration) {    ticker := time.NewTicker(duration)    // this will call daemon.doWork() periodically      go func() {        for {            <- ticker.C            daemon.doWork()        }    }()}type ConcreteDaemonA struct { foo int }type ConcreteDaemonB struct { bar int }func (daemon *ConcreteDaemonA) doWork() {    daemon.foo++    fmt.Println("A: ", daemon.foo)}func (daemon *ConcreteDaemonB) doWork() {    daemon.bar--    fmt.Println("B: ", daemon.bar)}func main() {    dA := new(ConcreteDaemonA)    dB := new(ConcreteDaemonB)    start(dA, 1 * time.Second)    start(dB, 5 * time.Second)    time.Sleep(100 * time.Second)}這不會編譯,因?yàn)椴豢赡軐⒔涌谟米鹘邮掌鳌J聦?shí)上,我已經(jīng)回答了我的問題(見下面的答案)。但是,這是實(shí)現(xiàn)這種邏輯的慣用方法嗎?除了語言的簡單性之外,還有什么理由不使用默認(rèn)實(shí)現(xiàn)嗎?
查看完整描述

3 回答

?
烙印99

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超13個贊

其他答案為您的問題提供了替代方案,但是他們提出了不使用抽象類/結(jié)構(gòu)的解決方案,我想如果您有興趣使用類似抽象類的解決方案,這里是您問題的非常精確的解決方案:

package main


import (

    "fmt"

    "time"

)


type Daemon interface {

    start(time.Duration)

    doWork()

}


type AbstractDaemon struct {

    Daemon

}


func (a *AbstractDaemon) start(duration time.Duration) {

    ticker := time.NewTicker(duration)


    // this will call daemon.doWork() periodically  

    go func() {

        for {

            <- ticker.C

            a.doWork()

        }

    }()

}




type ConcreteDaemonA struct { 

*AbstractDaemon

foo int

}


func newConcreteDaemonA() *ConcreteDaemonA {

  a:=&AbstractDaemon{}

  r:=&ConcreteDaemonA{a, 0}

  a.Daemon = r

  return r

}



type ConcreteDaemonB struct { 

*AbstractDaemon

bar int

}


func newConcreteDaemonB() *ConcreteDaemonB {

  a:=&AbstractDaemon{}

  r:=&ConcreteDaemonB{a, 0}

  a.Daemon = r

  return r

}




func (a *ConcreteDaemonA) doWork() {

    a.foo++

    fmt.Println("A: ", a.foo)

}


func (b *ConcreteDaemonB) doWork() {

    b.bar--

    fmt.Println("B: ", b.bar)

}



func main() {

    var dA  Daemon = newConcreteDaemonA()

    var dB  Daemon = newConcreteDaemonB()


    dA.start(1 * time.Second)

    dB.start(5 * time.Second)


    time.Sleep(100 * time.Second)

}

如果這仍然不明顯如何在 go-lang 中使用抽象類/多繼承,這里是具有全面詳細(xì)信息的帖子。


查看完整回答
反對 回復(fù) 2021-10-04
?
神不在的星期二

TA貢獻(xiàn)1963條經(jīng)驗(yàn) 獲得超6個贊

如果您想提供“默認(rèn)”實(shí)現(xiàn)(for Daemon.start()),那不是接口的特性(至少在 Go 中不是)。這是具體(非接口)類型的特征。


所以Daemon在你的情況下應(yīng)該是一個具體的類型,struct因?yàn)槟阆M凶侄?,所以很方便。并且要完成的任?wù)可以是一個接口類型的值,或者在簡單的情況下只是一個函數(shù)值(簡單的情況意味著它只有一個方法)。


帶接口類型

在Go Playground上試用完整的應(yīng)用程序。


type Task interface {

    doWork()

}


type Daemon struct {

    task Task

}


func (d *Daemon) start(t time.Duration) {

    ticker := time.NewTicker(t)

    // this will call task.doWork() periodically

    go func() {

        for {

            <-ticker.C

            d.task.doWork()

        }

    }()

}


type MyTask struct{}


func (m MyTask) doWork() {

    fmt.Println("Doing my work")

}


func main() {

    d := Daemon{task: MyTask{}}

    d.start(time.Millisecond*300)


    time.Sleep(time.Second * 2)

}

帶函數(shù)值

在這個簡單的例子中,這個較短。在Go Playground上試一試。


type Daemon struct {

    task func()

}


func (d *Daemon) start(t time.Duration) {

    ticker := time.NewTicker(t)

    // this will call task() periodically

    go func() {

        for {

            <-ticker.C

            d.task()

        }

    }()

}


func main() {

    d := Daemon{task: func() {

        fmt.Println("Doing my work")

    }}

    d.start(time.Millisecond * 300)


    time.Sleep(time.Second * 2)

}


查看完整回答
反對 回復(fù) 2021-10-04
?
九州編程

TA貢獻(xiàn)1785條經(jīng)驗(yàn) 獲得超4個贊

一個簡單的解決方案是移動daemon *Daemon到參數(shù)列表(從而start(...)從界面中刪除):


type Daemon interface {

    // start(time.Duration)

    doWork()

}


func start(daemon Daemon, duration time.Duration) { ... }


func main() {

    ...

    start(dA, 1 * time.Second)

    start(dB, 5 * time.Second)

    ...

}


查看完整回答
反對 回復(fù) 2021-10-04
  • 3 回答
  • 0 關(guān)注
  • 332 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號