3 回答

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ì)信息的帖子。

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)
}

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)
...
}
- 3 回答
- 0 關(guān)注
- 332 瀏覽
添加回答
舉報(bào)