Here is a sample code, I want to call interface function
throw a struct
package main
import (
"fmt"
"time"
)
type Person interface {
sayHello()()
}
func sayHello()() {
fmt.Printf("hello\n")
}
type Foo struct {
num int
person Person
}
var FooChan = make(chan *Foo, 200)
func say() () {
for {
select {
case f := <-FooChan:
f.person.sayHello() // runtime error here
fmt.Printf("num %v\n", f.num)
}
}
}
func main()(){
var foo Foo
foo.num = 2
FooChan <- &foo
go say()
time.Sleep(10*time.Second)
}
I want to call sayHello()
throw interface
, this Person interface
may be defined in another file. I get panic: runtime error: invalid memory address or nil pointer dereference
when I run it. How can I call sayHello()
?
You need to create a struct that implements the interface Person.
type IImplementPersonMethod struct {}
func (IImplementPersonMethod) sayHello()() {
fmt.Printf("hello\n")
}
Then inside the Foo, you pass this struct, so your code should be: (i removed the ()() on main function, since main is func dont need it and it can result on a warning)
package main
import (
"fmt"
"time"
)
type Person interface {
sayHello()()
}
type IImplementPersonMethod struct {}
func (IImplementPersonMethod) sayHello()() {
fmt.Printf("hello\n")
}
type Foo struct {
num int
person Person
}
var FooChan = make(chan *Foo, 200)
func say() () {
for {
select {
case f := <-FooChan:
f.person.sayHello() // runtime error here
fmt.Printf("num %v\n", f.num)
}
}
}
func main(){
var foo Foo
foo.num = 2
foo.person=IImplementPersonMethod{}
FooChan <- &foo
go say()
time.Sleep(10*time.Second)
}
From https://www.geeksforgeeks.org/interfaces-in-golang/ :
Go language interfaces are different from other languages. In Go language, the interface is a custom type that is used to specify a set of one or more method signatures and the interface is abstract, so you are not allowed to create an instance of the interface. But you are allowed to create a variable of an interface type and this variable can be assigned with a concrete type value that has the methods the interface requires. Or in other words, the interface is a collection of methods as well as it is a custom type.
So here if you want to make the channel generic for the types which implement the Person interface may be you want create different types like farmer, doctor and you just want to call this say
method like
func say() {
for {
select {
case f := <-FooChan:
f.sayHello()
}
}
}
And you just pass the different person in the channel and will get the output of the person type's sayHello() method's output
An example is given below. May this will help to clear you concept with golang's interface:
package main
import (
"fmt"
"time"
)
type Person interface {
sayHello()
}
func(f *Farmer) sayHello() {
fmt.Printf("hello from farmer\n")
fmt.Printf("num %d\n", f.num)
}
type Farmer struct {
num int
Person
}
type Doctor struct {
num int
Person
}
func(f *Doctor) sayHello() {
fmt.Printf("hello from doctor\n")
fmt.Printf("num %d\n", f.num)
}
var FooChan = make(chan Person, 200)
func say() {
for {
select {
case f := <-FooChan:
f.sayHello()
}
}
}
func main(){
foo := &Farmer{
num: 2,
}
FooChan <- foo
go say()
foo2 := &Doctor{
num: 1,
}
FooChan <- foo2
time.Sleep(10*time.Second)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.