Skip to content

Instantly share code, notes, and snippets.

@arnehormann
Created September 23, 2013 10:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arnehormann/6669006 to your computer and use it in GitHub Desktop.
Save arnehormann/6669006 to your computer and use it in GitHub Desktop.
usage example for reflect.MakeFunc: create panic-on-error wrappers which do not pass the error (in a comfortable but probably rather slow way)
import "reflect"
// assumption for fptr: func with error as last argument
func makeMust(fptr interface{}) {
must := func(in []reflect.Value) []reflect.Value {
if err := in[len(in)-1]; !err.IsNil() {
panic(err.Interface())
}
return in[:len(in)-1]
}
fn := reflect.ValueOf(fptr).Elem()
v := reflect.MakeFunc(fn.Type(), must)
fn.Set(v)
}
@arnehormann
Copy link
Author

This snippet sacrifices a little speed to easily create error-munging wrappers but still handle the errors (with a panic).

Here's an example:

import (
    "database/sql"
    "fmt"
    "reflect"
)

var (
    mustDB   func(*sql.DB, error) *sql.DB
    mustStmt func(*sql.Stmt, error) *sql.Stmt
    mustRows func(*sql.Rows, error) *sql.Rows
    mustScan func(error)
)

func init() {
    makeMust(&mustDB)
    makeMust(&mustStmt)
    makeMust(&mustRows)
    makeMust(&mustScan)
}

func doDBStuff() {
    db := mustDB(sql.Open("mysql", "root@tcp(localhost:3306)/"))
    defer db.Close()
    show := mustStmt(db.Prepare("SHOW GLOBAL VARIABLES"))
    defer show.Close()
    rows := mustRows(show.Query())
    defer rows.Close()
    receiver := make([]interface{}, 2)
    for rows.Next() {
        mustScan(rows.Scan(receiver...))
        fmt.Printf("%v\t%v\n", receiver[0], receiver[1])
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment