在Go语言中,当将任何接口作为参数时,可以简化类型转换。

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

Simplify casting in Go when taking any interface as a parameter

问题

我有一个类似这样的结构体:

  1. //
  2. // HandlerInfo 用于在功能中注册网关处理程序
  3. type HandlerInfo struct {
  4. Fn func(interface{})
  5. FnName string
  6. FnRm func()
  7. }

我想传递一个函数:

  1. func StarboardReactionHandler(e *gateway.MessageReactionAddEvent) {
  2. // foo
  3. }
  4. i := HandlerInfo{Fn: StarboardReactionHandler}

不幸的是,这会导致以下错误:

  1. 无法将 'StarboardReactionHandler'(类型为 func(e *gateway.MessageReactionAddEvent))用作类型为 func(interface{}) 的类型

我找到了这个解决方法:

  1. func StarboardReactionHandler(e *gateway.MessageReactionAddEvent) {
  2. // foo
  3. }
  4. func handlerCast(e interface{}) {
  5. StarboardReactionHandler(e.(*gateway.MessageReactionAddEvent))
  6. }
  7. i := HandlerInfo{Fn: handlerCast}

有没有办法简化需要 handlerCast 的过程,比如在 StarboardReactionHandlerHandlerInfo 中进行处理?也许可以使用泛型或反射?我基本上只想尽量减少这里所需的语法/样板代码。

英文:

I have a struct like so,

  1. //
  2. // HandlerInfo is used by features in order to register a gateway handler
  3. type HandlerInfo struct {
  4. Fn func(interface{})
  5. FnName string
  6. FnRm func()
  7. }

where I want to pass a func:

  1. func StarboardReactionHandler(e *gateway.MessageReactionAddEvent) {
  2. // foo
  3. }
  4. i := HandlerInfo{Fn: StarboardReactionHandler}

Unfortunately, this results in:

  1. Cannot use 'StarboardReactionHandler' (type func(e *gateway.MessageReactionAddEvent)) as the type func(interface{})

I found this workaround:

  1. func StarboardReactionHandler(e *gateway.MessageReactionAddEvent) {
  2. // foo
  3. }
  4. func handlerCast(e interface{}) {
  5. StarboardReactionHandler(e.(*gateway.MessageReactionAddEvent))
  6. }
  7. i := HandlerInfo{Fn: handlerCast}

Is there some way that I can simplify needing handlerCast, such as doing it inside my StarboardReactionHandler or in HandlerInfo? Maybe with generics or reflection? I basically just want to minimize the syntax / boilerplate that's required here.

答案1

得分: 0

你可以使用interface{}.(type)来进行类型断言。

以下是一个示例:

  1. package main
  2. import "fmt"
  3. type HandlerInfo struct {
  4. Fn func(interface{})
  5. FnName string
  6. FnRm func()
  7. }
  8. type MessageReactionAddEvent = func(a, b int) int
  9. func StarboardReactionHandler(e interface{}) {
  10. switch e.(type) {
  11. case MessageReactionAddEvent:
  12. fmt.Printf("%v\n", (e.(MessageReactionAddEvent))(1, 2))
  13. }
  14. }
  15. func add(a, b int) int {
  16. return a + b
  17. }
  18. func main() {
  19. i := HandlerInfo{Fn: StarboardReactionHandler}
  20. i.Fn(add)
  21. }

希望对你有帮助!

英文:

you can use interface{}.(type)

follow is a exmple:

  1. package main
  2. import "fmt"
  3. type HandlerInfo struct {
  4. Fn func(interface{})
  5. FnName string
  6. FnRm func()
  7. }
  8. type MessageReactionAddEvent = func(a, b int) int
  9. func StarboardReactionHandler(e interface{}) {
  10. switch e.(type) {
  11. case MessageReactionAddEvent:
  12. fmt.Printf("%v\n", (e.(MessageReactionAddEvent))(1, 2))
  13. }
  14. }
  15. func add(a, b int) int {
  16. return a + b
  17. }
  18. func main() {
  19. i := HandlerInfo{Fn: StarboardReactionHandler}
  20. i.Fn(add)
  21. }

huangapple
  • 本文由 发表于 2022年5月23日 11:17:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/72342938.html
匿名

发表评论

匿名网友

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

确定