Need suggestion for which code is better

I want to create linked list code in Go but not sure which style should I use.

*** First Code Start****

package main

import "fmt"

type List struct {
	head *Node
}

type Node struct {
	next    *Node
	element int
}

func (list *List) append(element int) {
	if list.head == nil {
		list.head = &Node{nil, element}
	} else {
		node := list.head
		for node.next != nil {
			node = node.next
		}
		node.next = &Node{nil, element}
	}
}

func (list *List) appendFirst(element int) {
	list.head = &Node{list.head, element}
}

func (list *List) Print() {
	node := list.head
	for node != nil {
		fmt.Print(node.element, " ")
		node = node.next
	}
	fmt.Println("")
}

func main() {
	ll := List{}
	for i := 0; i < 10; i++ {
		ll.appendFirst(i)
		// ll.append(i)
	}
	ll.Print()
}

*** First Code Stop****

*** Second Code Start****

package main

import "fmt"

type List *Node

type Node struct {
	next    List
	element int
}

func append(list *List, element int) {
	if *list == nil {
		*list = &Node{nil, element}
	} else {
		append(&((*list).next), element)
	}
}

func appendFirst(list *List, element int) {
	*list = &Node{*list, element}
}

func Print(list List) {
	node := list
	for node != nil {
		fmt.Print(node.element, " ")
		node = node.next
	}
	fmt.Println("")
}

func main() {
	var list List = nil
	for i := 0; i < 10; i++ {
		appendFirst(&list, i)
		//append(&list, i)
	}
	Print(list)
}

*** Second Code Stop****

Please let me know which code style should be used.

methods and functions are both valid; a method is just a function with a special receiver argument. Practically it doesn’t make much of a difference. A rule of thumb that some people follow, is to use methods when managing state, as it flows naturally. Note you can also write pointer receivers to modify the value that the receiver is pointing at.

Thanks for the reply.

But this answer does not solve my problem. Consider If you are a Go developer how you will write a linked list program. Is there some other much better program.

If I was a go developer, I’d use the linked list from the stdlib.

5 Likes

Ahh… we don’t write Linked List with Go. In fact, we don’t use it at all. It’s very very rare we encounter a use case for it.

We got garbage collector, hashmap (map) and slice (don’t confuse with array). Linked List only makes sense in languages without them like C.

In fact, you already put us in a difficult situation for writing a code without proper use case, a career suicide to anyone of us. :rofl:

It’s call prepend

She’s right. The person to determine is your reviewer, interviewer, boss, and customer. Both are fine.

Be careful with your naming convention. In Go, begin with Capital letter means exported function. Please go through Effective Go - The Go Programming Language

I prefer double pointer implementation. Refer: Double Pointers and Linked List in C | Dev Notes

HOWEVER, keep in mind that whatever you’re doing (both samples) in proper Go is:

func main() {
    var list []int

	// append
	for i := 0; i < 10; i++ {
		list = append(list, i)
	}

	// prepend
	for i := 0; i < 10; i++ {
		list = append([]int{i}, list...)
	}
}

Wrong language bro.

1 Like

Thanks for the reply.

You are right we can use built-in data structures directly and done. But some professor is teaching linked list using go. I had given OOPs based answer and he is not happy with my solution. So I guess, I should go with double pointer based procedural solution.

Naming convention i will fix. But the question is what should be the approach to write code procedural or oops based.

Thanks for the reply.

You are right we can use built-in data structures directly and done. But some professor is teaching linked list using go. I had given OOPs based answer and he is not happy with my solution. So I guess, I should go with double pointer based procedural solution.

Are you absolutely sure your lecturer really expecting a LL in Go or something outside the box (it’s quite obvious)?

I had 1 lecturer once secretly expected me to lift a 5+3kg weights with just a bag of raw spaghetti in a structural integrity assignment before while my peers were using other materials like metal wires. The hidden expectation was the business acumen of things like costing and product life-cycle planning (the building only need to have 10 mins lifetime) on top of engineering technicalities.


Site-note:

I’ll give my deepest sigh if your lecturer is really expecting a LL from Go. Treat it like a simulation in life. Sometimes, it throws you lemon. Try make it a lemonade. Good luck. NOTE: the double pointer is totally doable in Go.

Ahhh… Go is not OOP. It does not polymorph or inherit a data type. Method 1 looks like OOP but it’s not.

The methods are duck-typing interfaces. You can’t change any already defined method and you can’t define a new data type to based on an existing definition along with all its methods without rewriting entirely - only composition.

Maybe he/she was disappointed because of this?

1 Like

Also, this function in sample 2 is conflicting with the built-in function append. Did you test your program before submitting it to your lecturer? Go developer can easily detect just by reading the code directly.

Could this be causing annoyance to your lecturer?

1 Like

Hi @hemant_jain ,

It is great that you are coding this data structure, and welcome to the Go forum.

Use the first approach, your first implementation. I think the second implementation is not the usual way to code in Go, I do not like the if *list == nil, as it has too many pointers and they make the code harder to read/write.

Now, when writing a data structure of any kind, you should also have a lot of unit tests. Also try to use generics (your list should be able to store any data type not just int).

Also make the append method public (Append), and add comments on top of the append method and the Node datastructure.

1 Like

Oh yeah… I nearly forgotten: try provide a complete Create, Read, Update, and Delete (CRUD) when developing an “unsafe” library. By right, the hardest part of LL is usually Delete because in C language, memory are managed manually. Since you’re in Go, the garbage collector will obviously back you up so you will have to consult your lecturer’s expecations whether the manual efforts are required in your demo.

You already done:

Append - add an element into the list to the last position
Prepend - add an element into the list to the first position
String - printout the list as string

Missing APIs are:

Len / Length - provide the total length of the list
Index - read value by position
Insert - add an element by position
Pop - remove an element by position
Search - scan index by value
Scan - scan all indices by value
Join - join 2 linked list into 1
Split - split 1 list into 2 different linked list
Copy - duplicate a list
Delete / Destroy - remove all elements by freeing the memory spaces and then the list
Sanitize - deep check each element is usable and safe.
Zero - set all element’s values to zero (usually security released where confidential data are zeroed out after use, before free).
Reserve - reserve and initialise a set of elements in the list before use (used in time-sensitive environment like audio/video).

That’s all I believe. Please check with your deciding person. Good luck.

2 Likes

This is a great idea @hollowaykeanho. You should also have an interface with these methods, and your data structure implements it. When people look at your code, they will see the interface and have a clear idea of what functionality you offer.

hi @sylvie,

Thank you for your answer, I think that you are onto something. What do you mean by “Single purpose package favors functions pattern” ?

What is this functions pattern ? Indeed the strings package exposes some functions (not an object implementing an interface), but a data structure is an object offering functionality. Please give more details.

my style