FAQ
Okay, I struggled a bit with pointers and did some reading... apparently
interfaces are *always* pointers to structs (?) which makes something like
*interface{} completely redundant in my case.

So I worked on my queue and it's now storing pointers to Node instances,
rather than copying them - I think... can you guys confirm?

package main


import "fmt"


// A generic Queue that can hold any interface type:


type Queue struct {

     head *Item

     tail *Item

}


type Item struct {

     value interface {}

     next *Item

}


func (q *Queue) Push(value interface {}) {

     item := &Item{value, nil}



     if q.tail != nil {

         q.tail.next = item

     }



     q.tail = item



     if q.head == nil {

         q.head = q.tail

     }

}


func (q *Queue) Pop() interface{} {

     if q.head == nil {

         panic("the queue is empty - use CanPop() before calling Pop()")

     }



     value := q.head.value



     q.head = q.head.next



     return value

}


func (q *Queue) CanPop() bool {

     return q.head != nil

}


// A custom element type and matching Queue type for it:


type Node struct {

     number int

}


type NodeQueue struct {

     Queue

}


func NewNodeQueue() NodeQueue {

     return NodeQueue{Queue{}}

}


func (q *NodeQueue) Push(n *Node) {

     q.Queue.Push(n)

}


func (q *NodeQueue) Pop() *Node {

     return q.Queue.Pop().(*Node)

}


func main() {

     q := NewNodeQueue()


     fmt.Printf("can pop? %t\n", q.CanPop())


     q.Push(&Node{0})

     fmt.Printf("can pop? %t\n", q.CanPop())

     fmt.Printf("pop: %d\n", q.Pop().number)



     q.Push(&Node{1})

     q.Push(&Node{2})

     q.Push(&Node{3})



     fmt.Printf("pop: %d\n", q.Pop().number)

     fmt.Printf("pop: %d\n", q.Pop().number)

     fmt.Printf("pop: %d\n", q.Pop().number)



     fmt.Printf("can pop? %t\n", q.CanPop())

}


Did I get it right? :-)


On Fri, Dec 27, 2013 at 9:08 AM, Rasmus Schultz wrote:

You could also just lowercase the variable name, that would keep it
private to the package.

You could still modify it after triggering and receiving the error object,
I suppose - but that's an even more far-fetched scenario ;-)

Note that I'm not looking for ways to make things "fool proof" or directly
prevent a developer from doing something stupid (or evil) - what I look
for, typically, is a design that communicates well what the *intended*use is. My attitude is: if you decide to break from obvious, good patterns
that were put out there as the first option for you, that's your problem,
not mine ;-)

Also, sometimes, code has legitimate uses that the author didn't foresee.
Perhaps not often, but it happens, and I'm not a fan of building road
blocks or providing training wheels for somebody who wants to take the road
less traveled :-)


On Wed, Dec 25, 2013 at 6:46 PM, Luther wrote:

On Wednesday, December 25, 2013 2:53:43 PM UTC-5, mikhae...@gmail.comwrote:
Don't worry so much about making this a var. This is fairly common for
types that cannot be consts. For instance, it's used for errors all over:

http://golang.org/src/pkg/net/udpsock.go?s=191:270
What's preventing someone from writing ErrWriteToConnected = foo, and
screwing everything up?
I don't see how you could make that mistake without actively trying to
screw up. First of all, you'd have to qualify ErrWriteToConnected with the
package name. Next, you'd have to make sure the value has an Error method.
Also, when you refer to an error by its variable name, it's usually to test
for equality, so the only thing that gets messed up is the error message
output.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

People

Translate

site design / logo © 2022 Grokbase