Why GoLang Method gives Compile Error? - go

I am a trying the Methods in GoLang. I am a newbie so please correct me if I am asking dumb question.
The link says that we can write the Methods as normal Functions. But when I try following code it gives me compile error as
a.sq undefined (type MyFloat has no field or method sq)
The commented lines in following code are working as expected though.
Please help me. Following is my code:
package main
import (
"fmt"
)
type MyFloat float64
func sq (f MyFloat) string {
return fmt.Sprintln("The square is: ", f*f)
}
/*func (f MyFloat) sq() string {
return fmt.Sprintln("The square is: ", f*f)
}*/
func main() {
a := MyFloat(2.0)
fmt.Println(a.sq())
}

You are declaring sq as a function, not a method. If you want to attach sq to MyFloat, you should declare it like:
func (f MyFloat) sq() string {
return fmt.Sprintln("The square is: ", f*f)
}
This way you will be able to do a.sq().

Related

Why does adding an Error() method change program behavior in Go?

The program below prints "2.5"
package main
import (
"fmt"
)
type myFloat64 float64
// func (f myFloat64) Error() string {
// return fmt.Sprintf("Error with %v", f)
// }
func main() {
var a myFloat64 = myFloat64(2.5)
fmt.Printf("%v\n", a)
}
Interestingly, when I uncomment the Error() method, the program no longer prints "2.5"
Question:
Why does adding an Error() method change program behavior? Pointers to the Go language specification explaining this behavior would be much appreciated.
myFloat64 implements the error interface:
type error interface {
Error() string
}
fmt.Println() will consider a as an error value, and print the error message by calling a.Error(), which executes fmt.Sprintf("Error with %v", f). But Sprintf behaves just like Println, it also considers f as an error value and calls Error(). This recursion goes infinitely and causes stack overflow.

trying to create reusable append to struct in go

i am trying to make reusable method / func in go to push valu struct to another slice/ array in struct
i tried like this
import (
"fmt"
)
type ErrorValidate struct {
ErrorKey string
Message string
}
type ValidateMessage struct {
ErrorMessage []*ErrorValidate
}
func (v *ValidateMessage) AddError(err ErrorValidate) {
v.ErrorMessage = append(v.ErrorMessage, &err)
}
func main() {
s1 := *ValidateMessage{}
s1.AddError(&ErrorValidate{"theKey", "string"})
fmt.Println(*s1)
}
got error invalid indirect of ValidateMessage literal (type ValidateMessage)
the link here https://play.golang.org/p/VjdsiZQLroF
on those case i have a func for Validate something and then i tried to push error message on ErrorValidate , but i keep using append in my conditional, i am trying to make it reduce but got error above
There are a couple problems in your code. This one is generating your error (nothing to do with your append, or that method at all):
s1 := *ValidateMessage{}
This is not valid syntax. You probably meant s1 := &ValidateMessage{}.
s1.AddError(&ErrorValidate{"theKey", "string"})
You're trying to pass a *ErrorValidate to a function that takes a ErrorValidate. This should be s1.AddError(ErrorValidate{"theKey", "string"}).

Trying to implement OOPS in golang with structs

I am trying to retain the stats of a struct. What I am trying to do is create a struct using NewGolang and increase the counter, but all the output are 1. I am expecting 1,2,3. Can somebody please explain.
package main
import "fmt"
type Golang struct {
SessionCounter int
}
func NewGolang() *Golang {
return &Golang{
SessionCounter: 0,
}
}
func (g Golang) increaseCounter() {
g.SessionCounter++
fmt.Println(g.SessionCounter)
}
func main() {
obj := NewGolang()
obj.increaseCounter()
obj.increaseCounter()
obj.increaseCounter()
}
Output:
1
1
1
Expected:
1
2
3
When you run method without pointer you copy struct data, when use poiner you change original data.
Change func (g Golang) increaseCounter() to func (g *Golang) increaseCounter(). You need pointer receiver to change the data inside the struct.

How to convert a user-defined named type/struct to it's anonymous type

The original question
I have the following Go code. I would like to handle Foo a struct or Bar a type as a string. With "handle" I mean that I would like to convert/cast/whatever it's underlaying value to the (real) type string. I have a workaround, but I find it unintuitive in the case of a struct.
Going for a Type (instead of a struct) seems the better approach. I don't need to maintain any state, nor do I have any need for "inheriting" type specific functionality, so in my case it should work. However a call to type.String() causes stack recursion. I'm mostly curious if I'm not missing something (obvious).
package main
import "fmt"
type Foo struct {
string
}
func (f *Foo) String() string {
return f.string
}
type Bar string
func (b *Bar) String() string {
return fmt.Sprintf("%s", b) // Cannot use: return string(b) here.
}
func main() {
a := Foo{"a"}
var b Bar
b = "b"
fmt.Printf("A is: %s\n", a) // Doesn't call a.String() ?
//fmt.Printf("A is: %s\n", string(a)) // Doesn't work
fmt.Printf("A is: %s\n", a.string) // workaround A
fmt.Printf("A is: %s\n", a.String()) // workaround B, required if I want to use it in a different package
fmt.Printf("B is: %s\n", b) // Calls b.String()
fmt.Printf("B is: %s\n", string(b))
//fmt.Printf("B is: %s\n", b.String()) // Causes a stack overflow
}
Output:
A is: {a}
A is: a
A is: a
B is: b
B is: b
Code on Go's Playground: https://play.golang.org/p/zgrKao4cxa
The behaviour is from Go version 1.5.2
Answers
The following are short examples based on the answers of my original questions. Also, the following post helped in understanding and reasoning of the subject: Value receiver vs. Pointer receiver in Golang?
In case of a type, the following works:
type MyString string
func (b MyString) String() string {
return string(b)
}
Go's Playground link: https://play.golang.org/p/H12bteAk8D
In case of a struct, the following works:
package main
import "fmt"
type MyString struct {
string
someState int
}
func (m MyString) String() string {
return string(m.string)
}
func main() {
// The verbose version:
//var a MyString = MyString{string: "a", someState: 1}
a := MyString{"a", 1}
fmt.Printf("A is: %s\n", a)
fmt.Printf("A is: %s\n", a.String())
}
Go's Playground link: https://play.golang.org/p/GEKeY4rmB8
You've made a pointer receivers for your String methods, but you are working with values, not pointers to them, so it wouldn't apply. You need to switch to pointers or change String methods signatures:
package main
import "fmt"
type Foo struct {
string
}
func (f Foo) String() string {
return "My " + f.string
}
type Bar string
func (b Bar) String() string {
return fmt.Sprintf("My %s", string(b))
}
func main() {
a := Foo{"a"}
var b Bar = "b"
fmt.Printf("A is: %s\n", a)
fmt.Printf("B is: %s\n", b)
}
Please, be careful with receivers type:
The rule about pointers vs. values for receivers is that value methods
can be invoked on pointers and values, but pointer methods can only be
invoked on pointers
Oh, and one more thing. fmt.Sprintf("%s", b) will call String method if it's defined. So, you'll get a recursion.

Is this a closure example?

I am reading Closure example in Mark Summerfield's book Programming in Go Section 5.6.3. He defines Closure as a "function which "captures" any constants and variables that are present in the same scope where it is created, if it refers to them."
He says that one use of closure is anonymous functions (or function literals in Go)
He gives this examples:
addPng := func(name string) string { return name + ".png" }
addJpg := func(name string) string { return name + ".jpg" }
fmt.Println(addPng("filename"), addJpg("filename"))
I understand that anonymous function named addPng is a wrapper for the string concatenation operator +.
If I understand correctly, he is assigning an anonymous function a name then calling the function with that name. I don't see the point of this example. If I define the same function addPng and call it inside main() I get the same result:
package main
import ("fmt")
func addPng (name string) string {
return name + ".png"
}
func main() {
fmt.Println(addPng("filename"))
}
I understand that I cannot define and use a function inside another function. But why is the anonymous function in Summerfield's example called "Closure"? And why use a wrapper function? What am I missing?
Here's an example of using a closure for state representation.
package main
import "fmt"
func NextFibonacci() func() int {
a, b := 0, 1
return func() (f int) {
f, a, b = a, b, a+b
return
}
}
func main() {
nf := NextFibonacci()
f := make([]int, 7)
for i := range f {
f[i] = nf()
}
fmt.Println(len(f), f)
}
Output:
7 [0 1 1 2 3 5 8]
It's not for the first time I see someone referring to this particular book where the cited material is either plain wrong or basically missing the point completely.
Let me stop talking about the book here by suggesting to not use it at all.
For a good and correct definition of a closure, see Wikipedia. Pay attention to the adjective 'lexical'.

Resources