求助:关于参数为interface的函数指针传递

redunit · 2020-03-05 12:35:09 · 1881 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2020-03-05 12:35:09 的主题,其中的信息可能已经有所发展或是发生改变。

代码如下:

package main

import (
    "fmt"
)

type Task struct {
    f func(i interface{})
}

func NewTask(h func(interface{})) (t *Task) {
    t = &Task{
        f: h,
    }
    return
}

func (t *Task) Run() {
    fmt.Println("Runing...")
}

func test1(i *int) error {
    fmt.Println("test1", i)
    // do something here
    // ...
    return nil
}

func test2(s *string) (err error) {
    fmt.Println("test2", s)
    // do otherthing here
    // ...
    return
}

func main() {
    t1 := NewTask(test1)
    t2 := NewTask(test2)

    t1.Run()
    t2.Run()
}

报错: .\main.go:33:15: cannot use test1 (type func(int) error) as type func(interface {}) in argument to NewTask .\main.go:34:15: cannot use test2 (type func(string) error) as type func(interface {}) in argument to NewTask

请教诸位如何修改?谢谢


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1881 次点击  
加入收藏 微博
9 回复  |  直到 2020-03-08 11:37:00
focusonline
focusonline · #1 · 5年之前

亲,请使用markdown格式化你的代码. 否则看不懂而且缺东西?

daiyudong
daiyudong · #2 · 5年之前
package main

import "fmt"

type task struct {
    f func(i interface{})
}

func (t *task) run() *task {
    return &task{
        f: func(i interface{}) {
            fmt.Println(i)
        },
    }
}

func allType() *task {
    return &task{
        f: func(i interface{}) {
            fmt.Println(i)
        },
    }
}

func main() {
    a := allType()
    a.f("aaa")
    var b task
    b1 := b.run()
    b1.f("bbb")

}

是不是就是想简单实现这个??

redunit
redunit · #3 · 5年之前

@daiyudong 谢谢回复 我是想把处理函数传进去,每个Task有不同的处理函数。

anxk
anxk · #4 · 5年之前

函数返回类型也是函数类型的一部分,func (*int) error 和 func (interface{}) error 这俩没法直接转换

jarlyyn
jarlyyn · #5 · 5年之前

1.你对interface{}有误解

2.你这个场景需要的不是传入函数,而是建立一个task 的 interface,然后把这个interface传进去

a7505553
a7505553 · #6 · 5年之前

伪代码

type task interface{
    Run()
}

type t1 struct{}

func(t *t1) Run(){}

func NewTask() task{}

func main(){
    t := NewTask()
    t.Run()
}
Sinbad
Sinbad · #7 · 5年之前

感觉你是想要多态。 https://www.jianshu.com/p/b333c5f34ef6 参考一下。

focusonline
focusonline · #8 · 5年之前

golang是不支持泛型的, 所以你设计的参数传递不能实现, 你只能做成这样:

package main

import (
    "fmt"
)

type Task struct {
    f func(i interface{}) (error)
}

func NewTask(h func(interface{}) (error)) (t *Task) {
    t = &Task{
        f: h,
    }
    return
}

func (t *Task) Run() {
    fmt.Println("Runing...")
}

func test1(i interface{}) error {
    fmt.Println("test1", i)
    // do something here
    // ...
    return nil
}

func test2(s interface{}) (err error) {
    fmt.Println("test2", s)
    // do otherthing here
    // ...
    return
}

func main() {
    fmt.Println("aa")
    t1 := NewTask(test1)
    t2 := NewTask(test2)

    t1.Run()
    t2.Run()
}

或者你可以使用context.Context来传递任何你想传递的参数

dequanLi
dequanLi · #9 · 5年之前

存在两个问题 1、test1和test2有返回值,task中f没有 2、func(i interface{})和test1(i *int)是不同的函数,也可以理解为两种不同的类型

package main

import (
    "errors"
    "fmt"
)

type Task struct {
    f func(i interface{}) error
}

func NewTask(h func(interface{}) error) (t *Task) {
    t = &Task{
        f: h,
    }
    return
}

func (t *Task) Run() {
    fmt.Println("Runing...")
}

func test1(i interface{}) error {
    // 类型断言一下
    intI,isOk := i.(int)
    if ! isOk {
        return errors.New("type is invalid")
    }

    fmt.Println("test1", intI)
    // do something here
    // ...
    return nil
}

func test2(s interface{}) (err error) {
    // 类型断言一下
    str,isOk := s.(int)
    if ! isOk {
        return errors.New("type is invalid")
    }


    fmt.Println("test2", str)
    // do otherthing here
    // ...
    return
}

func main() {
    t1 := NewTask(test1)
    t2 := NewTask(test2)

    t1.Run()
    t2.Run()
}
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传