gpt4 book ai didi

go - 使用接口(interface)为任意类型创建队列

转载 作者:IT王子 更新时间:2023-10-29 01:42:18 24 4
gpt4 key购买 nike

作为学习 Go 的练习,我正在编写一个基本的队列数据结构。我昨天开始学习接口(interface),我认为在这个练习中尝试使用它们会很酷。我想要完成的是拥有一个可以接受任何实现此接口(interface)的类型的 Queue:

type Queuable interface {
Next() *Queuable // This is probably not right
}

基本上,我想要的是能够将任何具有 Next() 方法的类型添加到我的 Queue 中。所以我尝试的是:

type Node struct {
value interface{}
next *Queuable
}

// Next gets the next object
func (n *Node) Next() *Queuable {
return n.next
}

// Job - A job for the queue
type Job struct {
instruction string
next *Queuable
}

// Next gets the next object
func (j *Job) Next() *Queuable {
return j.next
}

// Queue ...
type Queue struct {
head *Queuable
size int
}

我的方法看起来像:

func (q *Queue) Enqueue(node *Queuable) {
...
}

// Dequeue - Remove a Queueable form the Queue
func (q *Queue) Dequeue() *Queuable {
result := q.head
q.head = q.head.Next()
q.size--
return result
}

我遇到了很多这样的错误(基本上是在任何有赋值的行上):

current.Next undefined (type *Queuable is pointer to interface, not interface)

所以最终我想做的是:

func main() {
queue := NewQueue() // Helper function not pictured
job := &Job{"some instructions", nil}
node := &Node{5, nil}
queue.Enqueue(node) // queue = [node]
queue.Enqueue(job) // queue = [node, job]
queue.Dequeue() // node
queue.Dequeue() // job
}

最佳答案

不要使用指向接口(interface)类型的指针,只使用接口(interface)类型。

Queuable 是一种接口(interface)类型,因此在您使用 *Queuable 的代码中,将其更改为 Queuable。例如:

type Queuable interface {
Next() Queuable
}

type Node struct {
value interface{}
next Queuable
}

// Next gets the next object
func (n *Node) Next() Queuable {
return n.next
}

...

在 Go 中,接口(interface)类型的值存储一对:分配给变量的具体值,以及该值的类型描述符。

有关界面内部结构的更多信息:The Laws of Reflection #The representation of an interface

所以你几乎永远不需要接口(interface)指针。一个接口(interface)包含一个键值对,其中键可以是一个指针。指向接口(interface)的指针有意义的罕见情况是,如果您想修改传递给另一个函数的接口(interface)类型变量的值。

在您的示例中,类型 *Job 实现了 Queuable,因为它有一个接收方类型为 *Job 的方法,因此在任何地方都有一个值Queuable 是必需的,可以使用 *Job 的值(并且将创建和使用 Queuable 类型的隐式接口(interface)值)。

回到您的示例:

您的 Queuable 只定义了一种方法来获取队列中的下一个元素,但没有定义将其入队的方法,这将使该解决方案失去灵 active 。单个 Next() 方法仅描述它是“已排队”,但不是(必然)“可排队”

要成为queuable,我还要添加另一个方法:SetNext(Queuable)

type Queuable interface {
Next() Queuable
SetNext(Queuable)
}

它在 Node 上的实现可以是例如:

func (n *Node) SetNext(q Queuable) { n.next = q }

Go Playground 上试试.

另请注意,NodeJob 中存在一些代码重复,即 next 字段和 Next()SetNext() 方法。我们可以创建一个基本节点实现,例如:

type Base struct {
next Queuable
}

func (b *Base) Next() Queuable { return b.next }
func (b *Base) SetNext(q Queuable) { b.next = q }

现在您可以将此 Base 类型嵌入到具体的 NodeJob 实现中,这将“继承”next 字段和 Next()SetNext() 方法,因此您不必在 Node作业 类型。

这是 NodeJob 的完整实现,不需要其他任何东西:

type Node struct {
*Base
value interface{}
}

type Job struct {
*Base
instruction string
}

Go Playground 上试试这个.

关于go - 使用接口(interface)为任意类型创建队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35595810/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com