Передача возвращаемого значения пары в другую функцию напрямую - PullRequest
0 голосов
/ 07 марта 2020

Я вызываю функцию, которая возвращает пару (в примере os.Open), и я хочу передать возвращенную пару в качестве аргумента другой функции (без использования промежуточных переменных). Я пробовал два следующих способа, но безуспешно. Другие языки (например, F #) позволяют выполнять сопоставление с образцом при вызове функции. Как можно добиться того же в 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")
}

enter image description here

enter image description here

Ответы [ 3 ]

2 голосов
/ 07 марта 2020

Разрешение этого приведет к неоднозначному поведению; но вы могли бы закрыть последний аргумент и вернуть частично примененную функцию:

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))

Или наоборот:

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")
0 голосов
/ 07 марта 2020

Я нахожу это немного противоречивым, потому что следующее работает нормально, но когда добавлен дополнительный позиционный аргумент, компилятору это не нравится.

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
}

Очевидно, вы могли бы просто сделать pu sh return значение непосредственно, не уверен, что вы сильно потеряете, так как вы будете паниковать c, если ошибка не равна нулю

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")
}

Еще одна мысль - вы можете передать функцию и выполнить работу в 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")
 } 
0 голосов
/ 07 марта 2020

Благодаря подсказке Джека я вспомнил, что функции также можно вернуть. Следующее решение работает для меня

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")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...