- Published on
Debugging in Go
- Authors
- Name
- Mike Hacker
- @ki5ibd
Can you spot the errors?
package main
type ThatThing interface {
Print(...string)
}
type Thing struct {
Name string
token string
}
func NewThing(params ...string)(*ThatThing){
return &Thing {
Name: params.Name,
token: params.Token,
}
}
func (datThing *Thing) Print(...string) {
fmt.Println(datThing.Name)
fom.Println(...string)
}
func (datThing *Thing) Print2(...string) {
fmt.Println(datThing.Name)
fmt.Println(...string)
}
func (datThing *Thing) print(...string) {
fmt.Println(datThing.Name)
fmt.Println(...string)
}
t.Print("whatever")
Thing.Print2()
The provided Go code snippet contains several issues and misunderstandings. I'll explain the code's structure, its intended functionality, and the errors present.
Code Analysis
Package Declaration
package main
This line declares the main package, which is the starting point for a Go program.
Interface Definition
type ThatThing interface {
Print(...string)
}
The ThatThing
interface is defined with a single method Print
that takes a variadic number of strings (...string
).
Struct Definition
type Thing struct {
Name string
token string
}
The Thing
struct is defined with two fields: Name
and token
.
Constructor Function
func NewThing(params ...string) (*ThatThing) {
return &Thing {
Name: params.Name,
token: params.Token,
}
}
The NewThing
function is supposed to return a pointer to a ThatThing
interface. However, there are several issues here:
- The return type should be
*Thing
instead of*ThatThing
since it returns aThing
struct. - The way it tries to access
params.Name
andparams.Token
is incorrect.params
is a slice of strings, not a struct.
Method Implementations
func (datThing *Thing) Print(...string) {
fmt.Println(datThing.Name)
fmt.Println(...string)
}
func (datThing *Thing) Print2(...string) {
fmt.Println(datThing.Name)
fmt.Println(...string)
}
func (datThing *Thing) print(...string) {
fmt.Println(datThing.Name)
fmt.Println(...string)
}
- The
Print
method matches theThatThing
interface. However, the use offmt.Println(...string)
is incorrect and should befmt.Println(strings...)
. - The
Print2
andprint
methods are similar, but they are not part of theThatThing
interface. - Only exported methods (starting with an uppercase letter) can be part of an interface.
print
with a lowercase letter cannot fulfill theThatThing
interface.
Method Calls
t.Print("whatever")
Thing.Print2()
t.Print("whatever")
: This call is incorrect ast
is not defined.Thing.Print2()
: This call is incorrect asThing
is a type, not an instance.
Corrected Code
Here's the corrected version of the code:
package main
import (
"fmt"
)
type ThatThing interface {
Print(...string)
}
type Thing struct {
Name string
token string
}
func NewThing(params ...string) *Thing {
return &Thing{
Name: params[0],
token: params[1],
}
}
func (datThing *Thing) Print(strings ...string) {
fmt.Println(datThing.Name)
fmt.Println(strings...)
}
func (datThing *Thing) Print2(strings ...string) {
fmt.Println(datThing.Name)
fmt.Println(strings...)
}
func (datThing *Thing) print(strings ...string) {
fmt.Println(datThing.Name)
fmt.Println(strings...)
}
func main() {
t := NewThing("name1", "token1")
t.Print("whatever")
t.Print2("another", "test")
// t.print is not accessible here as it is unexported
}
Key Points and Fixes
- Correct Function Return Type: The
NewThing
function now correctly returns a*Thing
. - Parameter Handling: The parameters are accessed correctly from the
params
slice. - Variadic Parameters in Print Functions: Correctly passing the variadic parameters to
fmt.Println
. - Instance Method Calls: Method calls are now done on an instance of
Thing
, not on the type itself. - Unexported Method: The
print
method is unexported and not used outside its package.