猿问

函数是否必须满足函数类型的确切签名?

考虑以下简单的 go 程序


package main


import (

    "io"

    "encoding/json"

    "os"

)


type MyEncoder interface {

    Encode(v interface{}) error

}


type MyEncoderCreator func(io.Writer) *MyEncoder


type MyContainer struct {

    Creator MyEncoderCreator

}


func main() {

    container := Container{

        Creator:json.NewEncoder,

    }


    encoder := container.Creator(os.Stdout)

    encoder.Encode(map[string]string{"key":"value"})

}

此程序无法编译并出现以下错误:


./main.go:21: cannot use json.NewEncoder (type func(io.Writer) *json.Encoder) as type MyEncoderCreator in field value

为什么是这样?该json.Encoder结构有一个满足MyEncoder接口的接收器。那么是否应该json.NewEncoder允许将该功能分配给MyContainer.Creator?


肥皂起泡泡
浏览 178回答 1
1回答

忽然笑

是的,函数必须满足函数类型的确切签名。在其他情况下也会出现类似的情况:更正式的说法是Go 中的类型通常缺乏协方差。在这里,您可以包装json.NewEncoder一个返回的函数MyEncoder。我会使用值类型MyEncoder不是指针*MyEncoder,因为如果你存储一个指针内的接口值,那么通常你不也需要一个指针到该接口值只是为了避免副本; 如果有帮助,这里有更多关于指针与值的信息。
随时随地看视频慕课网APP

相关分类

Go
我要回答