改进扩展实现者之间的反射

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

Improve reflection between extended implementors

问题

我有一个Result接口,表示结果的最小状态。现在有不同的结构体实现了Result接口,但也添加了自己的方法。其中之一是SpecialResult,它实现了基本的Value()方法,还有一个特殊的Special()方法。

你可以在下面的代码片段中看到这个情况:

package main

import (
	"fmt"
	"reflect"
)

type Result interface {
	Value() string
}

type SpecialResult struct {
	value string
}

func (r *SpecialResult) Value() string {
	return r.value
}

func (r *SpecialResult) Special() string {
	return "look I am special!!"
}

func main() {
	sr := &SpecialResult{
		value: "1234",
	}

	doSomething(sr)
}

func doSomething(r Result) {
	switch reflect.TypeOf(r).String() {
	case "*main.SpecialResult":
		fmt.Printf("%s, %s\n", r.Value(), r.(*SpecialResult).Special())
		break
	default:
		fmt.Printf("%s\n", r.Value())
	}
}
  1. Playground
  2. Source

当你阅读代码的最后几行时,你可能会和我有同样的感觉:这看起来非常奇怪。

有没有更好的方法来实现这个设置?

Bodo

英文:

I have a Result interface which represents the minimum state of a result. Now there are different structs which implement the Result interface but also add own methods. One of them is SpecialResult which implemented the basic Value() method but also a special Special() method.

You can see this in the following snippet:

package main
 
import (
	"fmt"
	"reflect"
)
 
type Result interface {
	Value() string
}
 
type SpecialResult struct {
	value string
}
 
func (r *SpecialResult) Value() string {
	return r.value
}
 
func (r *SpecialResult) Special() string {
	return "look I am special!!"
}
 
func main() {
	sr := &SpecialResult{
		value: "1234",
	}
 
	doSomething(sr)
}
 
func doSomething(r Result) {
	switch reflect.TypeOf(r).String() {
	case "*main.SpecialResult":
		fmt.Printf("%s, %s\n", r.Value(), r.(*SpecialResult).Special())
		break
	default:
		fmt.Printf("%s\n", r.Value())
	}
}
  1. Playground
  2. Source

When you read the last lines of code you might feel the same as I do: This looks very weird.

Is there a better way to achieve the shown setup?

Bodo

答案1

得分: 4

使用类型断言

package main

import (
	"fmt"
)

type Result interface {
	Value() string
}

type SpecialResult struct {
	value string
}

func (r *SpecialResult) Value() string {
	return r.value
}

func (r *SpecialResult) Special() string {
	return "look I am special!!"
}

func main() {
	sr := &SpecialResult{
		value: "1234",
	}

	doSomething(sr)
}

func doSomething(r Result) {
	if special, ok := r.(*SpecialResult); ok {
		fmt.Printf("%s, %s\n", special.Value(), special.Special())
	} else {
		fmt.Printf("%s\n", r.Value())
	}
}

Playground

英文:

Use Type Assertions

package main

import (
	"fmt"
)

type Result interface {
	Value() string
}

type SpecialResult struct {
	value string
}

func (r *SpecialResult) Value() string {
	return r.value
}

func (r *SpecialResult) Special() string {
	return "look I am special!!"
}

func main() {
	sr := &SpecialResult{
		value: "1234",
	}

	doSomething(sr)
}

func doSomething(r Result) {
	if special, ok := r.(*SpecialResult); ok {
		fmt.Printf("%s, %s\n", special.Value(), special.Special())
	} else {
		fmt.Printf("%s\n", r.Value())
	}
}

Playground

huangapple
  • 本文由 发表于 2014年7月11日 19:23:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/24696563.html
匿名

发表评论

匿名网友

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

确定