在将结构体传递给interface{}的位置时出现错误。

huangapple go评论82阅读模式
英文:

Error while passing struct in the place of interface{}

问题

所以,我有一个像这样的函数:

func ProcessRequest(requestBody *SignInRequest, response func(SignInResponse) *src.Response, error func(ControllerError) *src.Response) *src.Response {
	return error(ControllerError{Code: http.StatusNotImplemented})
}

我试图调用它:

ProcessRequest(payload, myFunction, handler.OnControllerError)


func myFunction(i interface{}) *src.Response {

}

这显示了一个错误:

无法将'type func(i interface{}) *src.Response'用作'type func(SignInResponse) *src.Response'

但是,如果我尝试相同的操作:

type TestStruct struct {
	
}

func myFunction2(i interface{}) *src.Response {

}

myFunction2(TestStruct{})

那么就不会显示任何错误。

我希望它接受interface{}作为参数,因为我希望myFunction是通用的,可以接受任何struct

英文:

So, I have a function like this

func ProcessRequest(requestBody *SignInRequest, response func(SignInResponse) *src.Response, error func(ControllerError) *src.Response) *src.Response {
	return error(ControllerError{Code: http.StatusNotImplemented})
}

And I'm trying to call this

ProcessRequest(payload, myFunction, handler.OnControllerError)


func myFunction(i interface{}) *src.Response {

}

This is showing me an error

> Cannot use 'myFunction' (type func(i interface{}) *src.Response) as the type func(SignInResponse) *src.Response

But if I try the same thing with

type TestStruct struct {
	
}

func myFunction2(i interface{}) *src.Response {

}

myFunction2(TestStruct{})

Then it is not showing any error.

I want it to take interface{} as an argument because I want myFucntion to be general which can take any struct.

答案1

得分: 2

你混淆了两件事情。

当你有一个带有签名func (interface{}) *src.Response的函数时,你确实可以在调用时传递任何类型的值,但实际情况并非如此。

实际上,你有另一个函数ProcessRequest,其中一个参数的类型是func (SignInResponse) *src.Response的函数。
当你尝试将类型为func (interface{}) *src.Response的值传递给接受类型为func (SignInResponse) *src.Response的函数时,就会发生错误,因为这些参数的类型显然不兼容。

更新
要理解为什么参数的类型不兼容,可以考虑SignInResponseinterface{}在内存中具有不同的存储表示方式;基本上,这与[]T[]interface{}不兼容的原因相同,即使你可以执行t := T{}; var i interface{} = t。这个问题在FAQ中有解释

至于手头的问题,最简单的方法可能是使用匿名函数将SignInResponse的值“适配”为interface{}:传递类似以下的内容给ProcessResponse

func (r SignInResponse) *src.Response {
    return myFunction2(r)
}
英文:

You're confusing two things.

When you have a function with the signaure func (interface{}) *src.Response, you indeed can call it while passing it a value of any type, but that is not what happens.

What happens is that you have another function, ProcessRequest, and one of the types of its arguments is a function with the type func (SignInResponse) *src.Response.
The error happens when you try to pass a value of type func (interface{}) *src.Response to a function which accepts an argument of type func (SignInResponse) *src.Response because the types of these arguments are obviously not compatible.

Update.
To understand why the types of the arguments are not compatible, consider that SignInResponse and interface{} have different storage representation in memory; basically that's the same reason why []T and []interface{} are not compatible even when you can do t := T{}; var i interface{} = t. This one is explained in the FAQ.

As to the problem at hand, supposedly the easiest approach is to use an anonymous function to "adapt" the value SignInResponse to interface{}: pass to ProcessResponse something like

func (r SignInResponse) *src.Response {
    return myFunction2(r)
}

huangapple
  • 本文由 发表于 2022年2月14日 19:20:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/71111008.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定