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

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.

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

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

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)

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

How to call method which accepts slice of interface as parameters in golang? [duplicate]

This question already has answers here:
slice of struct != slice of interface it implements?
(6 answers)
Closed 5 years ago.
I want to call a method which accepts slice of interface as paramers in golang, but I find that I cannot pass it write as this:
type Base interface {
Run()
}
type A struct {
name string
}
func (a *A) Run() {
fmt.Printf("%s is running\n", a.name)
}
func foo1(b Base) {
b.Run()
}
func foo2(s []Base) {
for _, b := range s {
b.Run()
}
}
func TestInterface(t *testing.T) {
dog := &A{name: "a dog"}
foo1(dog)
// cat := A{name: "a cat"}
// foo1(cat)
s := []*A{dog}
foo2(s)
}
I get error like this:
cannot use s (type []*A) as type []Base in argument to foo2
If the function takes a []Base parameter, you must pass a []Base parameter. Not a []interface{}, not a []thingThatImplementsBase, but specifically a []Base. A slice of interfaces isn't an interface - it isn't "implemented by" a slice of any other type. The elements of a slice of interfaces can be anything that implements the interface, but the slice itself is of a strict and specific type.

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