转换Golang中的函数类型

Jas*_*hou 1 go

// Each type have Error() string method.
// The error built-in interface type is the conventional interface for
// representing an error condition, with the nil value representing no error.
//  type error interface {
//   Error() string
//  }

func (f binFunc) Error() string {
    return "binFunc error"
}

func func_type_convert() {
    var err error
    err = binFunc(add)
    fmt.Println(err)
    fmt.Println(i)
}
Run Code Online (Sandbox Code Playgroud)

我对上面的代码有两个问题:

  • Erroradd函数转换为binFunc类型时,我不知道为什么执行该方法?
  • 为什么add函数转换结果能够分配给错误的错误接口变量?

Cal*_*leb 7

error 是一个界面:

type error interface {
    Error() string
}
Run Code Online (Sandbox Code Playgroud)

这意味着任何具有方法的类型:Error() string履行接口并可以分配给类型的变量error.

binFunc 有这样一种方法:

func (f binFunc) Error() string {
    return "binFunc error"
}
Run Code Online (Sandbox Code Playgroud)

Go中的新开发人员有时会发现这一点令人困惑,因为他们没有意识到可以将方法附加到结构以外.在这种情况下binFunc定义喜欢这个:

type binFunc func(int, int) int
Run Code Online (Sandbox Code Playgroud)

所以它的工作方式是你可以转换任何具有相同签名的函数:(来自规范)

函数类型表示具有相同参数和结果类型的所有函数的集合.

所以如果你创建一个函数add:

func add(x, y int) int {
    return x + y
}
Run Code Online (Sandbox Code Playgroud)

您可以将其转换为binFunc:

binFunc(add)
Run Code Online (Sandbox Code Playgroud)

并且由于我们在上面定义的Error方法binFunc,我们然后能够将这个new分配给binFunc类型的变量error:

var err error
var bf binFunc = binFunc(add)
err = bf
Run Code Online (Sandbox Code Playgroud)

fmt.Println的行为是为你调用.Error()错误:

  1. 如果操作数实现了错误接口,则将调用Error方法将对象转换为字符串,然后根据动词的需要对其进行格式化(如果有).

那么回答你的问题:

  • Error执行该方法是因为fmt.Println查找类型的参数error,调用.Error()并打印结果字符串.
  • 您可以将binFuncs 分配给err因为binFuncError方法.您无法add直接分配,err因为它没有Error方法.但是您可以转换add为a,binFunc因为它们具有相同的函数签名,通过这样做,您可以将其分配给err变量.