英文:
How to pass interface to struct on golang
问题
这是一个示例代码,我想通过一个结构体调用interface
函数。
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() // 运行时错误发生在这里
fmt.Printf("num %v\n", f.num)
}
}
}
func main() {
var foo Foo
foo.num = 2
FooChan <- &foo
go say()
time.Sleep(10 * time.Second)
}
我想通过interface
调用sayHello()
函数,这个Person interface
可能在另一个文件中定义。当我运行它时,我得到了panic: runtime error: invalid memory address or nil pointer dereference
错误。我该如何调用sayHello()
函数?
英文:
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()
?
答案1
得分: 1
你需要创建一个实现Person接口的结构体。
type IImplementPersonMethod struct {}
func (IImplementPersonMethod) sayHello() {
fmt.Printf("hello\n")
}
然后在Foo结构体中传递这个结构体,所以你的代码应该是这样的:
(我删除了main函数上的()(),因为main是函数不需要它,否则会导致警告)
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() // 运行时错误在这里
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)
}
英文:
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)
}
答案2
得分: -1
从https://www.geeksforgeeks.org/interfaces-in-golang/:
Go语言的接口与其他语言不同。在Go语言中,接口是一种自定义类型,用于指定一个或多个方法签名的集合,接口是抽象的,因此不允许创建接口的实例。但是,您可以创建一个接口类型的变量,并且可以将该变量赋值为具有接口所需方法的具体类型值。换句话说,接口既是方法的集合,也是一种自定义类型。
因此,如果您想使通道对实现Person接口的类型进行泛型化,可能您想创建不同的类型,如农民(farmer)、医生(doctor),并且您只想调用此say
方法,如下所示:
func say() {
for {
select {
case f := <-FooChan:
f.sayHello()
}
}
}
您只需将不同的人传递到通道中,并将获得该人类型的sayHello()
方法的输出。
下面给出一个示例。希望这可以帮助您清楚Go语言接口的概念:
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)
}
英文:
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论