【问题标题】:assinging functions to function types that return interface values,将函数分配给返回接口值的函数类型,
【发布时间】:2018-05-02 21:33:25
【问题描述】:

我试图定义几个接口来重构一些代码,但我遇到了一个问题,Go 不允许我将函数分配给变量。 这是设置

main.go

    type Gettable interface {
        Get() int64
    }

    type MyFunction func(int64) (Gettable, error)

    func main() {

        var f MyFunction
        f = sub.TestFn2
        a, _ := f(1)
        fmt.Println(a)
    }

主/子

package sub

type MyStruct struct {
    Val int64
}

func (v MyStruct) Get() int64 {
    return v.Val
}

func TestFn2(a int64) (MyStruct, error) {
    return MyStruct{a}, nil
}

我正在尝试定义一个泛型函数类型,并在子包中创建具体函数

理想情况下,我想将函数存储在地图中并用类似的东西调用它们

FnMap["fnName"]()

我还没到,

我收到一个错误提示

/topics.go:27:4: cannot use sub.TestFn2 (type func(int64) (sub.MyStruct, error)) as type MyFunction in assignment

但是MyStruct明确实现了接口Gettable

【问题讨论】:

  • Go 中没有协方差:函数签名必须完全匹配。
  • 我建议将函数附加到type,这样会更简洁,也更惯用

标签: go


【解决方案1】:

由于签名不匹配而发生此错误。 您共享的代码是:

//shared code
//---------------------------------------------
type Gettable interface {
    Get() int64
}
type MyFunction func(int64) (Gettable, error)

所以你需要用 Gettable 替换 MyStruct。

//main/sub
//---------------------------------------------
type MyStruct struct {
    Val int64
}

func (v MyStruct) Get() int64 {
    return v.Val
}

//this signature of TestFn2 is different of MyStruct
//-[TestFn2] func (a int64) (MyStruct, error)
//-[MyFunction] func(int64) (Gettable, error)
func TestFn2(a int64) (Gettable, error) {//<-- replace by Gettable here
    return MyStruct{a}, nil
}

运行您的代码:

//main.go
//---------------------------------------------

func main() {
        var f MyFunction
        f = TestFn2
        a, _ := f(1)
        fmt.Println(a)
}   

结果是:

{1}

在操场上查看:https://play.golang.org/p/sRsXix8E_83

【讨论】:

    【解决方案2】:

    根据 Go 的 assignability rules,只有当变量的类型 Tf 的签名完全匹配时,函数 f 才能分配给变量 v

    在其他一些语言中分配更具体的类型称为“协变”的能力,而 Go 的类型系统没有。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-12
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多