Оценка короткого замыкания в Go - PullRequest
0 голосов
/ 11 декабря 2018

Мое понимание оценки короткого замыкания состоит в том, что выражение вызывается только в случае необходимости в операторе if.Следует ли Go за этим?

Например, могу ли я получить лучшую производительность в среднем от:

if !isValidQueryParams(&queries) || r == nil || len(queries) == 0 {
    return "", fmt.Errorf("invalid querystring")
}

... до этого:

if r == nil || len(queries) == 0 || !isValidQueryParams(&queries) {
    return "", fmt.Errorf("invalid querystring")
}

...поскольку isValidQueryParams - это функция с гораздо большим объемом служебной информации, чем r == nil или проверка длины карты?

, т. е. будет ли интерпретатор сначала вычислять r == ноль, увидит, что это правда, и не потрудится оценить другуюусловия?

РЕДАКТИРОВАТЬ: Неправильно называют оценку короткого замыкания как ленивая оценка

Ответы [ 3 ]

0 голосов
/ 11 декабря 2018

То, на что вы ссылаетесь, называется «оценкой короткого цирка», то есть подвыражения оцениваются с использованием нормальных правил ассоциативности только до тех пор, пока доступен полный результат, а оценка остальных выражений не будетизмените его в соответствии с правилами рассматриваемого двоичного оператора (ов).

В Go реализована оценка логических выражений при коротком замыкании (см. другой ответ ).

(@icza прокомментировал: несколько связанное: в коде Go выполняется оценка короткого замыкания, но механизм шаблонов Go не использует оценку короткого замыкания. Детали: Шаблон Golang и тестирование на действительные поля .)

«Ленивая оценка» - это совсем другое - обычно она реализуется в так называемых «функциональных» языках программирования, и она не реализуется напрямую в Go.


Сказав это, я бы отметил, что покаGo не поддерживает direct (как с синтаксисом и средой выполнения) для отложенной оценки, можетиспользоваться там, где это необходимо.

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

0 голосов
/ 11 декабря 2018

Спасибо Kostix и mkrieger за их ответы - они правильные, я имею в виду оценку короткого замыкания, а не ленивую оценку.

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

package main

import "fmt"

func main() {
    for i := 0; i < 10; i++ {
        if testFunc(1) || testFunc(2) {
            // do nothing
        }
    }
}

func testFunc(i int) bool {
    fmt.Printf("function %d called\n", i)
    return true
}

... который всегда будет давать:

$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
$ function 1 called
0 голосов
/ 11 декабря 2018

Это называется оценка короткого замыкания .Согласно этого руководства , логические операторы используют это:

Хотя в спецификации Go * явно не говорится, что Go использует оценку короткого замыкания,в нем упоминается, что

Логические операторы применяются к логическим значениям и дают результат того же типа, что и операнды.Правый операнд вычисляется условно.

Вот быстрый пример, чтобы доказать, что Go использует оценку короткого замыкания

[…]

...