How to pass string as parameter to Golang pointer receiver function? [duplicate] - go

This question already has an answer here:
"used as value" in function call
(1 answer)
Closed 4 years ago.
I am trying one simple Go struct with value and pointer receiver functions. I am not able to pass one string as an argument to pointer receiver function to modify the struct data. Can anyone please help on this?
Code:
package main
import (
"fmt"
)
type book struct {
author string
name string
category string
price int16
}
func (b book) greet() string {
return "Welcome " + b.author
}
func (b *book) changeAuthor(author string) {
b.author = author
}
func main() {
book := book{author: "Arockia",
name: "Python shortcuts",
category: "IT",
price: 1500}
fmt.Println(book.author)
fmt.Println(book.greet())
fmt.Println(book.changeAuthor("arulnathan"))
fmt.Println(book.author)
}
Error:
.\struct_sample.go:29:31: book.changeAuthor(string("arulnathan")) used as value

func (b *book) changeAuthor(author string) {
b.author = author
}
changeAuthor does not have a return type. You cannot use Println or any other function/method which expects a parameter in your case.
To solve this, first you can change your author as book.changeAuthor("arulnathan") and the print book.author.

You can not print changeAuthor while it return nothing.
book.changeAuthor("arulnathan")
fmt.Println(book.author)

Related

Initialize value for pointer in Go Generics [duplicate]

This question already has answers here:
How can I instantiate a non-nil pointer of type argument with generic Go?
(4 answers)
What is the generic type for a pointer that implements an interface?
(2 answers)
Closed 9 months ago.
I have a generic func func foo[T bar]() which I need to pass a type which is a pointer to a struct foo[*zab](). In func foo I want to initialize the value using one of new() or var t T.
My question is if that is possible and if, how! See the code below (with link to Go playground):
package main
import "fmt"
func main() {
foo[*zab]()
}
type bar interface {
String() string
SetString(string)
}
func foo[T bar]() {
var t T
t.SetString("asdf")
fmt.Println(t.String()) // Should return "asdf"
}
type zab struct {
f string
}
func (z zab) String() string {
return z.f
}
func (z *zab) SetString(f string) {
z.f = f
}
https://go.dev/play/p/rLCuvYNem1t

why is this method definition syntax accepted in Go? [duplicate]

This question already has answers here:
Is unnamed arguments a thing in Go?
(3 answers)
Closed 1 year ago.
the code
package main
import "fmt"
type unimplementedGreeterServer struct {
}
func (unimplementedGreeterServer) SayHello() string {
return "hello"
}
func main() {
s := &unimplementedGreeterServer{}
ret := s.SayHello()
fmt.Println(ret)
}
the result
hello
the question :
why the SayHello method has no unimplementedGreeterServer point or unimplementedGreeterServer receiver can run
I think the right will be
func (s unimplementedGreeterServer) SayHello2() string {
return "hello"
}
func (s *unimplementedGreeterServer) SayHello3() string {
return "hello"
}
not
func (unimplementedGreeterServer) SayHello() string {
return "hello"
}
The receiver itself is optional. If the method does not use the receiver, you can omit it. The declaration:
func (unimplementedGreeterServer) SayHello() string {
return "hello"
}
simply defines a method for unimplementedGreeterServer that does not use the receiver. It is defined for a value receiver, so it is defined for unimplementedGreeterServer and *unimplementedGreeterServer.

golang interface "used as value" error

package main
import (
"fmt"
)
type animal interface {
speak()
}
type dog struct {
name, sound string
}
type cat struct {
name, sound string
}
func (d dog) speak() {
fmt.Println(d.name, " goes ", d.sound)
}
func (c cat) speak() {
fmt.Println(c.name, " goes ", c.sound)
}
func animal_speak(a animal) {
fmt.Println(a.speak())
}
func main() {
dogo := dog{"scooby", "woof"}
cato := cat{"garfield", "meow"}
animal_speak(dogo)
animal_speak(cato)
}
When I call the animal interface it gives me the following error
./interface.go:28:21: a.speak() used as value
What am I doing wrong?
Link to playground
The interface is not used as a value. You're using a function call that returns nothing as a value.
speak() returns nothing... so what do you expect it to print?
Since you are printing the output of speak method, your speak method needs to return a string or an object whose string representation would print a string you would like to see. Here's your program modified https://play.golang.org/p/VDsp0cjXBd- to return a string.
This answer is based on all above answers,
Modified below function
Before
func animal_speak(a animal) {
fmt.Println(a.speak())
}
After
func animal_speak(a animal) {
a.speak()
}
Playgorund Link

Golang: Passing structs as parameters of a function

Trying to teach myself some Go by following an online course. And I'm trying to go a bit off course to expand on my learning a bit.
The course had us writing a simple function using a couple variables and the function would take the two variables and print out a line. So I had:
func main() {
var greeting := "hello"
var name := "cleveland"
message := printMessage(greeting,name)
fmt.Println(message)
}
func printMessage(greeting string, name string) (message string) {
return greeting + " " + name + "!"
}
Later the course introduced a way to create an pseudo-array of strings using the using the
func sayHello (cities ...string) (message string) {
for _, city := range cities {
message := printMessage("hello", city)
fmt.Println(message)
}
}
I would like to create a struct with different greetings and pass those into the sayHello function. So the struct and the variables would looks something like this:
type cityInfo struct {
greeting string
name string
wins float32
gamesPlayed float32
}
city1 := cityInfo{"hello", "cleveland"}
city2 := cityInfo{"good morning", "atlanta"}
...and so on
How do I format the function to pass those structs into the function so that I can iterate on the number of structs and get the greetings and names using city.greeting and city.name? Does this question make sense?
Function argument type can be any valid type:
func sayHello (cities ...cityInfo) {
for _, city := range cities {
message := printMessage(city.greeting, city.name)
fmt.Println(message)
}
}
One solution would be to create an interface and a greeting method.
For example:
type Greetable interface {
Greeting() string
Name() string
}
You would then implement the Greeting and Name methods in your struct (this would immediately implement the Greetable interface, due to the way that Go handles interfaces):
type cityInfo struct {
name string
greeting string
}
func (city *cityInfo) Greeting() string {
return city.greeting
}
func (city *cityInfo) Name() string {
return city.name
}
And then your function would just accept anything that implements Greetable:
func sayHello(greetables ...Greetable) (message string)
And use the Name() and Greeting() methods instead.

how to call child method in parent method? [duplicate]

This question already has an answer here:
Go embedded struct call child method instead parent method
(1 answer)
Closed 7 years ago.
package main
import "fmt"
type Super struct{}
func (super *Super) name() string {
return "Super"
}
func (super *Super) WhoAmI() {
fmt.Printf("I'm %s.\n", super.name())
}
type Sub struct {
Super
}
func (sub *Sub) name() string {
return "Sub"
}
func main() {
sub := &Sub{Super{}}
sub.WhoAmI()
}
I want to get "I'm Sub", but I get "I'm Super" instead.
I already know sub.WhoAmI will call sub.Super.WhoAmI, but I still want to know if there is a way to get "I'm Sub". In Python when I write following code:
class Super(object):
def name(self):
return "Super"
def WhoAmI(self):
print("I'm {name}".format(name=self.name()))
class Sub(Super):
def name(self):
return "Sub"
if __name__ == "__main__":
sub = Sub()
sub.WhoAmI()
I can get "I'm Sub".
Embedding is not subclassing. There are no superclasses or subclasses in Go. Sub here is not a "child" of Super. It contains a Super. You can't do you're trying to do. You need to organize your code in a different way so that it's not needed.
For example, here (playground) is a more natural way to do this in Go:
package main
import "fmt"
type Namer interface {
Name() string
}
type Super struct{}
func (sub *Super) Name() string {
return "Super"
}
type Sub struct{}
func (sub *Sub) Name() string {
return "Sub"
}
func WhoAmI(namer Namer) {
fmt.Printf("I'm %s.\n", namer.Name())
}
func main() {
sub := &Sub{}
WhoAmI(sub)
}
Rather than focus on classes (which Go doesn't have), this focuses on interfaces. It's not a question of what things are, it's a question of what they can do. This is a very powerful approach to programming, and in practice is often much more flexible and less error-prone than inheritance abstractions.
Think of functions in Go as if they all belong to a single namespace. Go really doesn’t have classes, methods, or inheritance, so what you’re attempting will never work the way you intend.
To put it another way, when you define a function like this:
func (f *Foo) DoStuff()
You can imagine it really being defined as:
func DoStuff(f *Foo)
So you might notice why Go chose to call the name function on your Super struct—it was the only function signature that matched. (Note that in your WhoAmI function super is defined as super *Super so Go matches it up with the corresponding function of the same type.)
As for how you might do this the Go way, try using interfaces:
http://play.golang.org/p/8ELw-9e7Re
package main
import "fmt"
type Indentifier interface {
WhoAmI() string
}
type A struct{}
func (a *A) WhoAmI() string {
return "A"
}
type B struct{}
func (b *B) WhoAmI() string {
return "B"
}
func doSomething(x Indentifier) {
fmt.Println("x is a", x.WhoAmI())
}
func main() {
doSomething(&A{})
doSomething(&B{})
}

Resources