使用反射和DRY原则优化代码

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

Use of reflection and DRYing out some code

问题

我有一个函数,需要接收一个类型,确定子类型,然后创建子类型的副本。我一直盯着这个函数看,感觉可以简化,但就是想不出如何让它正常工作。以下是代码:

  1. func AddProp(prop prop, x, y int) []prop {
  2. v := reflect.ValueOf(prop)
  3. fmt.Printf("Prop类型是 %v", v.Type())
  4. switch v.Type() {
  5. case reflect.TypeOf(&Fence{}):
  6. f := Fence{}
  7. f.New(x, y)
  8. props = append(props, &f)
  9. case reflect.TypeOf(&Rock{}):
  10. f := Rock{}
  11. f.New(x, y)
  12. props = append(props, &f)
  13. }
  14. return props
  15. }

实际上,代码比这个要长得多,有更多的情况。谢谢你的帮助!

编辑:
很合理的问题 - 什么是 prop?

  1. type prop interface {
  2. New(int, int)
  3. }

第二次编辑:
我的结构体看起来像这样:

  1. type Prop struct {
  2. fullImage image.Image
  3. x, y int
  4. }
  5. type Fence struct {
  6. Prop
  7. horizontal bool
  8. }

我已经为两者定义了 New(x, y int) 方法:

  1. func (p *Prop) New(x, y int)
  2. func (p *Fence) New(x, y int)

我需要获取 Fence 结构体并基于 Fence 而不是 Prop 调用 New 方法。

英文:

I have a function that needs to receive a type, determine the subtype, then create a copy of the subtype. I keep staring at this function and I feel this can be simplified, but I just can't figure out how to get it functioning. Here's the code:

  1. func AddProp(prop prop, x, y int) []prop {
  2. v := reflect.ValueOf(prop)
  3. fmt.Printf("Prop type is %v", v.Type())
  4. switch v.Type() {
  5. case reflect.TypeOf(&Fence{}):
  6. f := Fence{}
  7. f.New(x, y)
  8. props = append(props, &f)
  9. case reflect.TypeOf(&Rock{}):
  10. f := Rock{}
  11. f.New(x, y)
  12. props = append(props, &f)
  13. }
  14. return props
  15. }

It's actually quite a bit longer than this with many more cases. Thank you for taking a look!

Edit:
Perfectly reasonable question - what is a prop?

  1. type prop interface {
  2. New(int, int)
  3. }

Second Edit:
My structs looks like this:

  1. type Prop struct {
  2. fullImage image.Image
  3. x, y int
  4. }
  5. type Fence struct {
  6. Prop
  7. horizontal bool
  8. }

I have New(x,y int) defined for both

  1. func (p *Prop) New(x, y int)
  2. func (p *Fence) New(x, y int)

I need to get the Fence struct and call the New based on the Fence and not the Prop

答案1

得分: 0

你可以简化这段代码,前提是所有类型都有New方法:

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. func main() {
  7. props := AddProp(&Rock{}, 1, 1)
  8. fmt.Printf("%#v\n", props)
  9. props = AddProp(&Fence{}, 1, 1)
  10. fmt.Printf("%#v\n", props)
  11. }
  12. type Rock struct{}
  13. func (r *Rock) New(x, y int) {}
  14. type Fence struct{}
  15. func (r *Fence) New(x, y int) {}
  16. type prop interface {
  17. New(x, y int)
  18. }
  19. func AddProp(p prop, x, y int) (props []prop) {
  20. newValue := reflect.New(reflect.TypeOf(p).Elem()).Interface()
  21. z := newValue.(prop)
  22. z.New(x, y)
  23. props = append(props, z)
  24. return props
  25. }
英文:

You can simplify this provided all types have the New method:

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. func main() {
  7. props := AddProp(&Rock{}, 1, 1)
  8. fmt.Printf("%#v\n", props)
  9. props = AddProp(&Fence{}, 1, 1)
  10. fmt.Printf("%#v\n", props)
  11. }
  12. type Rock struct{}
  13. func (r *Rock) New(x, y int) {}
  14. type Fence struct{}
  15. func (r *Fence) New(x, y int) {}
  16. type prop interface {
  17. New(x, y int)
  18. }
  19. func AddProp(p prop, x, y int) (props []prop) {
  20. newValue := reflect.New(reflect.TypeOf(p).Elem()).Interface()
  21. z := newValue.(prop)
  22. z.New(x, y)
  23. props = append(props, z)
  24. return props
  25. }

huangapple
  • 本文由 发表于 2021年8月4日 21:59:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/68652630.html
匿名

发表评论

匿名网友

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

确定