препятствует условию в предыдущем утверждении условия if - PullRequest
0 голосов
/ 11 октября 2018

У меня проблемы с оператором if, который включает условие для предыдущей части оператора предложения if.

В этом упрощенном примере я хочу расширить поиск по идентификатору дотакже поиск по имени с необязательным префиксом, который будет предпочтительным.

Код псевдо:

IF I have a prefix AND I can find a record using the prefix and name
THEN override the record ID
ELSE IF I can find a record using name
THEN override the record ID
ELSE do something else to override the record ID

В bash это будет просто:

if test -n "$PREFIX" && id_=$(GetByName "$PREFIX:$id")
then id="$id_"
elif id_=$(GetByName "$id")
then id="$id_"
elif id_=$(legacy_attempt "$id")
then id="$id_"
fi

Нокак выразить это в го?

Это неправильно:

if PREFIX != "" && n, err := GetByName(PREFIX + ":" + id) && err == nil {
    id = n.ID
} else if n, err := GetByName(id) && err == nil {
    id = n.ID
} else if n, err := legacy_attempt(id) && err == nil {
    id = n
}

Я предполагаю, потому что средняя часть последовательности && является выражением, а не выражением (в отличие от C).

Я пробовал использовать = вместо := и иметь err и g, объявленные вне области видимости, но это не помогает.

Я пробовал такие ужасы как:

if if PREFIX != "" { n, err := GetByName(PREFIX + ":" + id) } ; err == nil {

, но ошибки были больше, чем ошибки видимости n и err, go утверждали, что ожидало выражение после if, хотя я былпытаясь дать ему предыдущее утверждение, состоящее из if

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

Есть ли здесь какие-нибудь полезные идиомы go , чтобы помочь?

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

* И я имею в виду уродливый из-за двух else if предложений.

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Более чистое решение - определить вспомогательную функцию:

func getId(prefix string, name string) (int, error) {
    if (prefix != "") {
        if n, err := GetByName(prefix + ":" + name); err == nil {
            return n.ID, nil
        }
    }
    return GetByName(name)
}

и вызвать функцию следующим образом:

if newId, err := getId(prefix, name) {
   id = newId
}
0 голосов
/ 11 октября 2018

Вы не можете сделать это с помощью одного оператора if, поэтому используйте 2 из них.И вы можете использовать переменную «state» для отслеживания успешности первого поиска:

found := false
if PREFIX != "" {
    if n, err := GetByName(PREFIX + ":" + id); err == nil {
        id, found  = n.ID, true
    }
}
if !found {
    if n, err := GetByName(id); err == nil {
        id = n.ID
    }
}

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

func lookup(name string, id *string) (ok bool) {
    if n, err := GetByName(name); err == nil {
        *id = n.ID
        return true
    }
    return false
}

При этом ваша первоначальная задача будет выглядеть следующим образом:

_ = PREFIX != "" && lookup(PREFIX+":"+id, &id) || lookup(id, &id)

Правильность приведенной выше строки основана на оценке короткого замыкания логики бул.То есть, если PREFIX не пусто, и первый поиск выполнен успешно, второй поиск не будет вызван.Если PREFIX пусто или первый поиск «потерпит неудачу», будет вызван второй поиск.

Несмотря на то, что эта 2-я версия очень компактна, я все равно выберу первый, более подробный, но более чистыйрешение.В конечном итоге ваша цель состоит не в том, чтобы написать самый компактный код, а в наиболее читаемом и наиболее удобном для обслуживания коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...