Reputation: 2886
I call a function that returns a pair (in the example os.Open) and I want to pass the returned pair directly as argument to another function (without using intermediate variables). I have tried the two following ways, unsuccessfully. Other languages (like F#) allow to perform pattern matching on function call. How can I achieve the same in Go?
func checkError(f *os.File, e error, m string) interface{} {
if e != nil {
/*Print m and panic*/
}
return f
}
func f1(path string) {
checkError(os.Open(path), "Can't Open File") //ERROR
}
func checkError((f *os.File, e error), m string) interface{} { //ERROR
if e != nil { /*Print m and panic*/}
return f
}
func f1(path string) {
checkError(os.Open(path), "Can't Open File")
}
Upvotes: 0
Views: 645
Reputation: 173522
Allowing this would result in ambiguous behaviour; but you could close over the last argument and return a partially applied function:
func checkError(m string) func(*os.File, error) {
return func(f *os.File, e error) {
if e != nil {
// do stuff with m
}
}
checkError("Can't Open File")(os.Open(path))
Or, the other way around:
func checkError(f *os.File, e error) func(string) {
return func(m string) {
if e != nil {
// do stuff with m
}
}
checkError(os.Open(path))("Can't Open File")
Upvotes: 2
Reputation: 4769
I find it a little inconsistent because the following works fine, but when the extra positional argument is added the compiler doesn't like it.
func checkError(f *os.File, e error) interface{} {
if e != nil {
/*Print m and panic*/
}
return f
}
func f1(path string) {
checkError(os.Open(path)) //ERROR
}
Obviously you could just push the return value directly, not sure you lose much since you'll panic if error isn't nil
func checkError(f *os.File, e error, m string) interface{} {
if e != nil {
/*Print m and panic*/
}
return f
}
func f1(path string) {
file, e := os.Open(path)
checkError(file, e, "Can't Open File")
}
Another thought is you could pass the function and do the work in checkError
type OsFunction func(string)(* os.File, error)
func checkError(osFunction OsFunction, path string, m string) interface{} {
f, e := osFunction(path)
if e != nil {
/*Print m and panic*/
}
return f
}
func f2(path string) {
checkError2(os.Open, path, "Can't Open File")
}
Upvotes: 0
Reputation: 2886
Thanks to Jack hint I remembered that functions can also be returned. The following solution works for me
func checkError(r interface{}, e error) func(string) interface{} {
return func(m string) interface{} {
if e != nil {
/*Print m and panic*/
}
return r
}
}
func f1(path string) {
checkError(os.Open(path))("Can't open file")
}
Upvotes: -1