用Go语言的reflect和interface进行重述
由于对golang的reflect和interface进行了各种试验,所以写下此备忘录。
反思
首先是关于 reflect 的,但我想要处理动态类型的那个部分。
不过,因为有一张反射表格,所以特别不需要解释了吧,我觉得实际写一下可能更容易理解。
Go 语言 reflect 反射表格。
界面
经常听到类似于方法列表的说法,但是在Golang中,可以简单地使用,而不需要像Java的接口那样写很多内容。这是一个常见的例子,就像这样。
package main
import (
"fmt"
)
type Animal interface {
Cry() string
}
type Dog struct{}
func (d *Dog) Cry() string {
return "わん"
}
type Cat struct{}
func (c *Cat) Cry() string {
return "にゃん"
}
func Sound(a Animal) {
fmt.Println(a.Cry())
}
func main() {
Sound(&Dog{})
Sound(&Cat{})
}
个人对这段代码感觉有些不对劲,于是进行了一些调查,似乎可以使用mixin?类似trait?的方式来实现。
混合?特征?
使用golang实现类似于php trait的东西可能有些奇怪,但可以使用interface来实现。让我稍微修改上面的示例代码。
package main
import (
"fmt"
)
type IAnimal interface {
Cry() string
}
type Animal struct {
IAnimal
}
type Dog struct{}
func (d *Dog) Cry() string {
return "わん"
}
type Cat struct{}
func (c *Cat) Cry() string {
return "にゃん"
}
func main() {
dog := Animal{&Dog{}}
fmt.Println(dog.Cry())
cat := Animal{&Cat{}}
fmt.Println(cat.Cry())
}
虽然没有对已经声明的Dog和Cat进行更改,但是现在增加了一个新的構造体Animal。它的内容基本上是直接将interface插入其中。
当然也可以给它起一个名字,但是这样一来在调用时就需要写出这个名字。
type Animal struct {
inf IAnimal
}
func main() {
dog := Animal{&Dog{}}
fmt.Println(dog.inf.Cry())
}
运用reflect动态地…
我本打算这样做的,但最后的结果是必须明确地在某个地方写下类型才能使其正常工作。我想做的是根据存储在数据库中的值来生成实例并调用函数,但是…在将值存储到结构体中并使用reflect编写的部分还不错,但在最初的处理中使用了switch结果。
package main
import (
"fmt"
"reflect"
"strconv"
)
type IContainer interface {
MethodA() string
MethodB(x, y int) int
}
type Driver struct {
IContainer
}
type DriverType int
const (
ADD = "ADD"
MINUS = "MINUS"
)
func CreateDriver(driver string) IContainer {
switch driver {
case ADD:
return &Add{}
case MINUS:
return &Minus{}
}
return nil
}
func New(driver string, args ...interface{}) *Driver {
container := CreateDriver(driver)
rt, rv := reflect.TypeOf(container).Elem(), reflect.ValueOf(container).Elem()
for i, arg := range args {
field := rt.Field(i)
value := rv.FieldByName(field.Name)
value.Set(reflect.ValueOf(arg))
}
return &Driver{container}
}
type Add struct {
Value int
}
func (c *Add) MethodA() string {
return strconv.Itoa(c.Value)
}
func (c *Add) MethodB(x, y int) int {
return (x + y) + c.Value
}
type Minus struct {
Value int
Digit int
}
func (c *Minus) MethodA() string {
return fmt.Sprintf("%d, %d", c.Value, c.Digit)
}
func (c *Minus) MethodB(x, y int) int {
return c.Value - (x+y)*c.Digit
}
func main() {
a := New("ADD", 193)
fmt.Println(a.MethodA())
fmt.Println(a.MethodB(9, 3))
m := New("MINUS", 200, 3)
fmt.Println(m.MethodA())
fmt.Println(m.MethodB(3, 9))
}
去游乐场
虽然我写了很多东西,学到了很多东西,但我仍然感觉自己的理解还不够深入。如果有更好的写作方式,请务必告诉我。