【问题标题】:Can methods be created for function types?可以为函数类型创建方法吗?
【发布时间】:2019-11-15 06:32:42
【问题描述】:

我知道可以为特定类型创建方法

例子

type MyFunc func() int

func (f MyFunc) eval() int {
    return f()
}

func main() {
   var randomFunction MyFunc = func() int {
      return 1;
  }

  fmt.Println(randomFunction.eval()) // prints 1
}

但是randomFunction 必须声明为MyFunc 类型。如果声明看起来像

randomFunction := func() int {
  return 1;
}

方法调用不会起作用。

我的问题是,例如,是否可以为 func () int 类型的每个函数创建方法。

我知道 Go 不是函数式的,也不包含太多函数式习语,但我正在寻找一种类似于 Haskell 的函数显示实例的方法:

instance Show (Int -> Int) where
   show op = show "Function with 1 Int param and Int return type"

【问题讨论】:

    标签: function go methods


    【解决方案1】:

    方法被“绑定”到一个类型。 MyFunc.eval() 绑定到类型 MyFunc。

    这个:

    randomFunction := func() int {
      return 1
    }
    

    是一个short variable declaration,它创建一个名为randomFunction 的变量并使用函数字面量为其提供初始值,其类型将是匿名函数类型:func() int。此类型没有eval() 函数(匿名类型有零个方法)。

    但你可以使用conversion类型将其转换为MyFunc,结果值将具有该方法:

    randomFunction2 := func() int {
        return 1
    }
    fmt.Println(MyFunc(randomFunction2).eval()) // prints 1
    

    上述转换当然不会改变randomFucntion2的类型。

    如果您在短变量声明中使用转换,randomFunction3 将具有 MyFunc 的静态类型,并且“始终”具有 eval() 方法:

    randomFunction3 := MyFunc(func() int {
        return 1
    })
    fmt.Println(randomFunction3.eval()) // prints 1
    

    另外请注意,通常您甚至不必手动转换函数值,就像它是匿名类型一样,转换会自动发生。

    例如,如果您有一个函数,其值类型为MyFunc:

    func handle(f MyFunc) {
        fmt.Println(f.eval())
    }
    

    您可以将上面的randomFunction2 传递给它:

    handle(randomFunction2) // This is OK
    

    上面的工作是因为randomFunction2 的值是assignable 到类型MyFunc 的(变量)(它们具有相同的基本类型)。详情请见Custom type passed to function as a parameter。

    试试Go Playground上的例子。

    【讨论】:

    • 除了在运行时转换为MyFunc,还可以为匿名函数类型创建方法吗?还是只针对您介绍的命名类型?
    • @DanBrezeanu 只能为 defined 类型创建方法。 Spec: Method declarations: "[接收者的] 类型必须是已定义类型T 或指向已定义类型T 的指针。"
    猜你喜欢
    • 1970-01-01
    • 2011-06-10
    • 2020-02-10
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    • 2013-03-24
    相关资源
    最近更新 更多