loading...

Reflection in Go: create a stack[T]

dannypsnl profile image 林子篆 Originally published at dannypsnl.github.io on ・2 min read

Do you know what can Go’s package reflect do?

Whatever you had to use it or not. Understanding it is not a bad thing.

A well-known thing is Go don’t have generic, I’m not going to tell you we have generic, I’m going to tell you some basic trick to have the result like generic.

Real world example: elz-lang/collection/stack

Elz is a language I’m developing, but that’s not the point. Point is this collection/stack using the trick I’m going to talk about.

Take a look on the type Stack

type Stack struct {
    stack []interface{}
    limitT *reflect.Type
}

limitT is a *reflect.Type, the reason that it’s a pointer to reflect.Type rather than reflect.Type is because we may do not spec it.

We add the Stack<T> by invoking WithT.

func (s *Stack) WithT(v interface{}) *Stack {
    t := reflect.TypeOf(v).Elem()
    s.limitT = &t
    return s
}

Why is reflect.TypeOf(v).Elem()? Because we can’t really get an instance that type is an interface! Instead of that, we can get a type is a pointer to an interface!

We have a common idiom is using (*SomeInterface)(nil) to get the pointer to interface instance.

Now we know that user code can be

type AST interface {
    Gen() llvm.Value
}

// main
s := stack.New().WithT((*AST)(nil))

After we do that, a user can’t push a value do not implement AST.

So, how we do that? We do a check at Push

func (s *Stack) Push(element interface{}) {
    if s.limitT != nil {
        if !reflect.TypeOf(element).Implements(*s.limitT) {
            panic(fmt.Sprintf("element must implement type: %s", *s.limitT))
        }
    }
    s.stack = append(s.stack, element)
}

If limitT is not nil, means we do not limit the type, just keep going on.

But if we limit the type, we check that element implements limitT or not.

If not, we panic the process.

Now we have a stack can promise to typesafe at runtime.

Posted on by:

dannypsnl profile

林子篆

@dannypsnl

I am a programming language theory lover; good at system software like Networking, OS.

Discussion

markdown guide