改善扩展实施者之间的反思

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
", r.Value(), r.(*SpecialResult).Special())
        break
    default:
        fmt.Printf("%s
", 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

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
", special.Value(), special.Special())
    } else {
        fmt.Printf("%s
", r.Value())
    }
}

Playground