2016-02-22 3 views
2

Вот, у меня есть выражение конъюнкции с участием некоторых функций, которые возвращают 2 значения:Избегайте вложения из функции, которая возвращает 2 значения в go?

if _, ok := f(); ok { 
    if _, ok := g(); !ok { 
    if h() { 
     if _, ok := i(); ok { 
     doStuff() 
     } 
    } 
    } 
} 

Могу ли я каким-то образом избежать вложенности? Вместо того, чтобы вложенность, я мог бы написать это как выражение в одной строке (я не могу полностью сломаться или вернуться раньше в этом случае)?

ответ

2

С помощью вспомогательной функции вы можете.

Создайте вспомогательную функцию, которая возвращает вторую bool возвращаемого значения, например:

func check(dummy interface{}, ok bool) bool { 
    return ok 
} 

и его использования:

if check(f()) && check(g()) && h() && check(i()) { 
    doStuff() 
} 

Обратите внимание, что это эквивалентно исходному код, потому что оператор && является оценивается слева направо и используется short-circuit evaluation: если какой-либо из операндов оценивается в false, дальнейшие операнды (функции) не будут вызываться.

Эта функция check() работает для всех функций, возвращающих 2 значения, а вторая имеет тип bool (поскольку любое значение может быть присвоено переменной типа interface{}).

Это описано в Spec: Calls:

В особом случае, если возвращаемые значения функции или метода g равны по количеству и по отдельности, присваиваемые параметрам другой функции или метода f , то вызов f(g(parameters_of_g)) будет вызывать f после привязки возвращаемых значений g к параметрам f по порядку. Вызов f не должен содержать никаких параметров, кроме вызова g, а g должен иметь как минимум одно возвращаемое значение. Если f имеет окончательный параметр ..., ему присваиваются возвращаемые значения g, которые остаются после назначения регулярных параметров.

Примечание: так как первый параметр в check() не используется, можно даже использовать пустой идентификатор, называя его, который сделает это очевидно, что мы не используем этот параметр:

func check(_ interface{}, ok bool) bool { 
    return ok 
} 
1

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

package main 

func f() (int, bool) { return 1, true } 

func g() (int, bool) { return 1, true } 

func h() bool { return true } 

func i() (int, bool) { return 1, true } 

func doStuff(f, g, i int) int { return f + g + i } 

func andDoStuff() { 
    ff, ok := f() 
    if !ok { 
     return 
    } 
    gg, ok := g() 
    if !ok { 
     return 
    } 
    if ok := h(); !ok { 
     return 
    } 
    ii, ok := i() 
    if !ok { 
     return 
    } 
    doStuff(ff, gg, ii) 

} 

func main() { 
    andDoStuff() 
} 
+0

В частности, заявитель сказал, что он не может вернуться в свое время. – icza

Смежные вопросы