Friday, August 19, 2011

A bit of Go language: type switch

Not a long time ago I discovered very useful Go language construct “type switch”.

switch t := someValue.(type) {
default:
    fmt.Printf("unexpected type %T", t)
case bool:
    fmt.Printf("boolean %t\n", t)
case int:
    fmt.Printf("integer %d\n", t)
case *bool:
    fmt.Printf("pointer to boolean %t\n", *t)
case *int:
    fmt.Printf("pointer to integer %d\n", *t)
}

Description in Effective Go

A switch can also be used to discover the dynamic type of an interface variable. Such a type switch uses the syntax of a type assertion with the keyword type inside the parentheses. If the switch declares a variable in the expression, the variable will have the corresponding type in each clause.

My use case

I have started writing bindings of libcurl for go language (https://github.com/dkucinskas/gocurl).
In libcurl we have C function: curl_easy_setopt(CURL *curl, CURLoption option, ...);

I'm using cgo utility for binding generation and this utility doesn’t support varargs yet. So I wrote wrapper function in C for each type of arguments. And then I needed way to know then to invoke each specific type of wrapper function. Here we have prefect case for type switch. Here follows the code:

func (e *Easy)SetOption(option Option, param interface{}) {
    switch v := param.(type) { 
    default:
        fmt.Printf("unexpected type %T", v)
    case uint64:
        e.code = Code(C.curl_wrapper_easy_setopt_long(e.curl, C.CURLoption(option), C.long(v)))
    case string:
        e.code = Code(C.curl_wrapper_easy_setopt_str(e.curl, C.CURLoption(option), C.CString(v)))
    } 
}