Early or late argument evaluation in golang?

huangapple go评论96阅读模式
英文:

Early or late argument evaluation in golang?

问题

在我的程序中,我按照以下方式进行一系列的顺序检查:

var value int

if !(ParseOrFail(inputStrVal, &value) &&
     Validate(value)) {
    return SomeErr
}

我知道只有当ParseOrFail返回true时才会调用Validate,但我不确定在所有这样的情况下它是否会得到更新后的值。

这样做是正确的吗?还是我必须将一个指针传递给Validate

Playground链接:https://play.golang.org/p/l6XHbgQjFs

英文:

In my program I do a series of sequential checks in this manner:

var value int

if !(ParseOrFail(inputStrVal, &value) &&
     Validate(value)) {
    return SomeErr
}

I know that Validate is called only if ParseOrFail returns true, but I'm not sure whether in all such scenarios it will get the updated value.

Is it correct to do so? Or must I pass a pointer to Validate ?

Playground link: https://play.golang.org/p/l6XHbgQjFs

答案1

得分: 6

你的代码行为在《Go编程语言规范》中有定义。

var value int

if !(ParseOrFail(inputStrVal, &value) && Validate(value)) {
    return SomeErr 
}

或者,用伪代码表示:

ParseOrFail的参数被评估
调用ParseOrFail
如果ParseOrFail == true
    Validate的参数被评估
    调用Validate

也就是说,在你的示例中(https://play.golang.org/p/l6XHbgQjFs),是延迟评估。

英文:

> The Go Programming Language
> Specification

>
> Expressions
>
> An expression specifies the computation of a value by applying
> operators and functions to operands.
>
> Operands
>
> Operands denote the elementary values in an expression. An operand may
> be a literal, a (possibly qualified) non-blank identifier denoting a
> constant, variable, or function, a method expression yielding a
> function, or a parenthesized expression.
>
> Order of evaluation
>
> At package level, initialization dependencies determine the evaluation
> order of individual initialization expressions in variable
> declarations. Otherwise, when evaluating the operands of an
> expression, assignment, or return statement, all function calls,
> method calls, and communication operations are evaluated in lexical
> left-to-right order.
>
> Calls
>
> Given an expression f of function type F,
>
> f(a1, a2, … an)
>
> calls f with arguments a1, a2, … an. Except for one special case,
> arguments must be single-valued expressions assignable to the
> parameter types of F and are evaluated before the function is called.
> The type of the expression is the result type of F. A method
> invocation is similar but the method itself is specified as a selector
> upon a value of the receiver type for the method.
>
> Logical operators
>
> Logical operators apply to boolean values and yield a result of the
> same type as the operands. The right operand is evaluated
> conditionally.
>
> && conditional AND p && q is "if p then q else false"
> || conditional OR p || q is "if p then true else q"
> ! NOT !p is "not p"

The behavior of your code is defined in The Go Programming Language Specification.

var value int

if !(ParseOrFail(inputStrVal, &value) && Validate(value)) {
    return SomeErr 
}

Or, in pseudocode,

ParseOrFail arguments are evaluated
ParseOrFail is called
if ParseOrFail == true
    Validate arguments are evaluated
    Validate is called

That is, in your example (https://play.golang.org/p/l6XHbgQjFs), late evaluation.

huangapple
  • 本文由 发表于 2017年4月14日 21:04:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/43412117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定