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

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

Use of reflection and DRYing out some code

问题

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

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

	v := reflect.ValueOf(prop)
	fmt.Printf("Prop类型是 %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
}

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

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

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 方法。

英文:

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:

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
}

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?

type prop interface {
	New(int, int)
}

Second Edit:
My structs looks like this:

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

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

func (p *Prop) New(x, y int)
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方法:

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
}
英文:

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

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
}

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:

确定