【问题标题】:Use of reflection and DRYing out some code使用反射和干掉一些代码
【发布时间】:2021-10-09 15:20:21
【问题描述】:

我有一个函数需要接收类型,确定子类型,然后创建子类型的副本。我一直盯着这个功能,我觉得这可以简化,但我就是不知道如何让它发挥作用。代码如下:

func AddProp(prop prop, x, y int) []prop {

  v := reflect.ValueOf(prop)
  fmt.Printf("Prop type is %v", v.Type())

  switch v.Type() {
  case reflect.TypeOf(&Fence{}):
      f := Fence{}
      f.New(x, y)
      props = append(props, &f)
  case reflect.TypeOf(&Rock{}):
      f := Rock{}
      f.New(x, y)
      props = append(props, &f)
  }
  return props
}

实际上比这长得多,还有更多案例。感谢您的观看!

编辑: 完全合理的问题 - 什么是道具?

type prop interface {
    New(int, int)
}

第二次编辑: 我的结构如下所示:

type Prop struct {
    fullImage image.Image
    x, y int
}
type Fence struct {
    Prop
    horizontal bool
} 

我为两者都定义了 New(x,y int)

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

我需要获取 Fence 结构并根据 Fence 而不是 Prop 调用 New

【问题讨论】:

  • 什么是道具??
  • Go 中没有子类型。
  • 一个名为 New 的函数不返回任何内容...感觉不像 Go。你到底想做什么?

标签: go reflection dry


【解决方案1】:

如果所有类型都具有New 方法,您可以简化此操作:

package main

import (
    "fmt"
    "reflect"
)

func main() {

    props := AddProp(&Rock{}, 1, 1)
    fmt.Printf("%#v\n", props)

    props = AddProp(&Fence{}, 1, 1)
    fmt.Printf("%#v\n", props)

}

type Rock struct{}

func (r *Rock) New(x, y int) {}

type Fence struct{}

func (r *Fence) New(x, y int) {}

type prop interface {
    New(x, y int)
}

func AddProp(p prop, x, y int) (props []prop) {
    newValue := reflect.New(reflect.TypeOf(p).Elem()).Interface()
    z := newValue.(prop)
    z.New(x, y)
    props = append(props, z)
    return props
}

【讨论】:

  • 它需要,我认为,一个额外的检查来测试给定的道具是否是一种 ptr。 play.golang.org/p/XQwt2-AQtth
  • 但我仍然不确定它是否应该始终将 ptr 返回到底层类型或与输入相同。
  • @mh-cbon,弄乱了指针,如果 prop 是指向结构的指针,更新后应该可以工作
  • neyh 抱歉,编译器仍然在抱怨 ;) 如果您不介意,我会更新。
  • 它必须传递指针,否则New(x,y) 在初始化底层结构的情况下将无法工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 2010-11-13
相关资源
最近更新 更多