Saltar para o conteúdo principal
Version: v20 BETA

An operator is a symbol or a group of symbols that you use to check, modify, or combine values. You are already familiar with many operators. For example, `1 + 2` uses the addition (or plus sign) operator to add two numbers together, and the result is 3. Comparison operators, like = or >, let you compare two or more values.

The 4D language supports the operators you may already know from other languages like C or JavaScript. However, the assignment operator is `:=` to prevent it from being mistakenly used when the equal to operator (`=`) is intended. Basic operators such as arithmetic operators (+, -, *, /, %...) and comparison operators (=, >, >=...) can be used with numbers, but also with boolean, text, date, time, pointer, or picture data types. Like JavaScript, the 4D language supports the concept of truthy and falsy values, which in use in short-cicrcuit operators.

## Terminologia​

The 4D language supports binary and ternary operators:

• binary operators operate on two targets (such as `2 + 3`) and appear in between their two targets.
• ternary operators operate on three targets. Like C, 4D has only one ternary operator, the ternary conditional operator (`a ? b : c`).

The values that operators affect are operands. Na expressão `1 + 2`, o símbolo + é um operador binário e os seus dois operandos são os valores 1 e 2.

The assignment operator (`a:=b`) initializes or updates the value of `a` with the value of `b`:

``\$myNumber:=3 //atribui 3 à variável MyNumber  \$myDate:=!2018/01/21! //assigns a date literal\$myLength:=Length("Acme") //assigns the result of the command (4) to \$myLength\$col:=New collection //\$col is initialized with an empty collection``

Do NOT confuse the assignment operator `:=` with the equality comparison operator `=`. A different assignment operator (and not `=`) was deliberately chosen to avoid issues and confusion which often occur with == or === in other programming languages. Esses erros são geralmente difíceis de reconhecer pelo compilador e geram problemas trabalhosos.

Operator results depend on the data types they are applied to. 4D supports different operators on scalar data types. They are described with the data types, in the following sections:

Histórico
VersãoMudanças

4D provides compound assignment operators that combine assignment with another operation. One example is the addition assignment operator (`+=`):

``\$a:=1 \$a+=2 // \$a=3``

The following compound assignment operators are supported:

AdiçãoText += TextText`\$t+=" World" //\$t:=\$t+" World"`
Number += NumberNúmero`\$n+=5 //\$n:=\$n+5`
Date += NumberDate`\$d+=5 //\$d:=\$d+5`
Time += TimeHora`\$t1+=\$t2 //\$t1:=\$t1+\$t2`
Time += NumberNúmero`\$t1+=5 //\$t1:=\$t1+5`
Picture += PictureImagem`\$p1+=\$p2 //\$p1:=\$p1+\$p2 (add \$p2 to the right of \$p1)`
Picture += NumberImagem`\$p1+=5 //\$p1:=\$p1+5 (move \$p1 horizontally 5 pixels to the right)`
SubtraçãoNumber -= NumberNúmero`\$n-=5 //\$n:=\$n-5`
Date -= NumberDate`\$d-=5 //\$d:=\$d-5`
Time -= TimeHora`\$t1-=\$t2 //\$t1:=\$t1-\$t2`
Time -= NumberNúmero`\$t1-=5 //\$t1:=\$t1-5`
Picture -= NumberImagem`\$p1-=5 //\$p1:=\$p1-5 (mover horizontalmente \$p1 5 pixels para a esquerda)`
DivisãoNumber /= NumberNúmero`\$n/=5 //\$n:=\$n/5`
Time /= TimeHora`\$t1/=\$t2 //\$t1:=\$t1/\$t2`
Time /= NumberNúmero`\$t1/=5 //\$t1:=\$t1/5`
Picture /= PictureImagem`\$p1/=\$p2 //\$p1:=\$p1/\$p2 (adicione \$p2 ao fundo de \$p1)`
Picture /= NumberImagem`\$p1/=5 //\$p1:=\$p1/5 (mover \$p1 verticalmente 5 pixels)`
MultiplicaçãoText *= NumberText`\$t*="abc" //\$t:=\$t*"abc"`
Number *= NumberNúmero`\$n*=5 //\$n:=\$n*5`
Time *= TimeHora`\$t1*=\$t2 //\$t1:=\$t1*\$t2`
Time *= NumberNúmero`\$t1*=5 //\$t1:=\$t1*5`
Picture *= NumberImagem`\$p1*=5 //\$p1:=\$p1*5 (redimensionar \$p1 por 5)`

These operators apply on any assignable expressions (except pictures as object properties or collection elements).

The operation "source `operator` value" is not strictly equivalent to "source := source `operator` value" because the expression designating the source (variable, field, object property, collection element) is only evaluated once. For example, in such expression as `getPointer()->+=1` the `getPointer` method is called only once.

Character indexing in text and byte indexing in blob do not support these operators.

#### Exemplos​

``// Addition\$x:=2\$x+=5 //\$x=7\$t:="Hello" \$t+=" World" //\$t="Hello World" \$d:=!2000-11-10!\$d+=10 //\$d=!2000-11-20!// Subtracção\$x1:=10\$x1-=5 //\$x1=5\$d1:=!2000-11-10!\$d1-=10 // \$d1=!2000-10-31!// Divisão\$x3:=10\$x3/=2 // \$x3=5// Multiplicação\$x2:=10\$x2*=5 // \$x2=10\$t2:="Hello" \$t2*=2 // \$t2="HelloHello"``

The && and || operators are short circuit operators. A short circuit operator is one that doesn't necessarily evaluate all of its operands.

The difference with the single & and | boolean operators is that the short-circuit operators && and || don't return a boolean value. They evaluate expressions as truthy or falsy, then return one of the expressions.

### Short-circuit AND operator (&&)​

Histórico
VersãoMudanças

A regra é a seguinte:

Dado `Expr1 && Expr2`:

The short-circuit AND operator evaluates operands from left to right, returning immediately with the value of the first falsy operand it encounters; if all values are truthy, the value of the last operand is returned.

The following table summarizes the different cases for the && operator:

Expr1Expr2Valor devolvido
truthytruthyExpr2
truthyfalsyExpr2
falsytruthyExpr1
falsyfalsyExpr1

#### Exemplo 1​

``var \$v : Variant\$v:= "Hello" && "World" //"World"\$v:=False && 0 // False\$v:=0 && False // False\$v:=5 && !00-00-00! // 00/00/00\$v := 5 && 10 && "hello" //"hello"``

#### Exemplo 2​

Digamos que tem uma loja online e que alguns produtos têm uma taxa de imposto aplicada e outros não.

To calculate the tax, you multiply the price by the tax rate, which may not have been specified.

Portanto, pode escrever isto:

``var \$tax : Variant\$tax:=\$item.taxRate && (\$item.price*\$item.taxRate)``

`\$tax` will be NULL if taxRate is NULL (or undefined), otherwise it will store the result of the calculation.

#### Exemplo 3​

Short-circuit operators are useful in tests such as:

``If((\$myObject#Null) && (\$myObject.value>10))    //code End if``

If \$myObject is Null, the second argument is not executed, thus no error is thrown.

### Short-circuit OR operator (||)​

Histórico
VersãoMudanças

The || operator returns the value of one of the specified operands. The expression is evaluated left to right and tested for possible "short-circuit" evaluation using the following rule:

Dado `Expr1 || Expr2`:

If Expr1 is truthy, Expr2 is not evaluated and the calculation returns Expr1.

If Expr1 is falsy, the calculation returns Expr2.

The following table summarizes the different cases and the value returned for the || operator:

Expr1Expr2Valor devolvido
truthytruthyExpr1
truthyfalsyExpr1
falsytruthyExpr2
falsyfalsyExpr2

#### Exemplo 1​

Say you have a table called Employee. Some employees have entered a phone number, and others haven't. Some employees have entered a phone number, and others haven't. Some employees have entered a phone number, and others haven't. This means that `\$emp.phone` could be NULL, and you cannot assign NULL to a Text variable. But you can write the following:

``var \$phone : Text\$phone:=\$emp.phone || "n/a"``

In which case `\$phone` will store either a phone number or the "n/a" string.

#### Exemplo 2​

Given a table called Person with a name field, as well as a maiden name field for married women.

The following example checks if there is a maiden name and stores it in a variable, otherwise it simply stores the person's name:

``var \$name: Text\$name:=\$person.maidenName || \$person.name``

### Precedência​

The `&&` and `||` operators have the same precedence as the logical operators `&` and `|`, and are evaluated left to right.

This means that `a || b && c` is evaluated as `(a || b) && c`.

Histórico
VersãoMudanças

The ternary conditional operator allows you to write one-line conditional expressions. For example, it can replace a full sequence of If… Else statements.

It takes three operands in the following order:

• uma condição seguida de um ponto de interrogação (?)
• an expression to execute if the condition is truthy, followed by a colon (:)
• an expression to execute if the condition is falsy

### Sintaxe​

A sintaxe é a seguinte:

`condition ? exprIfTruthy : exprIfFalsy`

Since the token syntax uses colons, we recommend inserting a space after the colon `:` or enclosing tokens using parentheses to avoid any conflicts.

### Exemplos​

#### Um exemplo simple​

``var \$age : Integervar \$beverage : Text\$age:=26\$beverage:=(\$age>=21) ? "Beer" : "Juice" ALERT(\$beverage) // "Beer"``

#### Handling data from a table​

This example stores a person's full name in a variable, and handles the case when no first name or last name has been specified:

``var \$fullname : Text// If one of the names is missing, store the one that exists, otherwise store an empty string\$fullname:=(\$person.firstname && \$person.lastname) ? (\$person.firstname+" "+\$person.lastname) : (\$person.lastname || \$person.firstname) || ""``

## Truthy e falsy​

Histórico
VersãoMudanças

As well as a type, each value also has an inherent Boolean value, generally known as either truthy or falsy.

truthy and falsy values are only evaluated by short-circuit and ternary operators.

The following values are falsy:

• false
• Null
• indefinido
• Null object
• Null collection
• Null pointer
• Null picture
• Null date !00-00-00!
• "" - Empty strings
• [] - Colecções vazias
• {} - Objectos vazios

Todos os outros valores são considerados truthy, incluindo:

• 0 - numeric zero (Integer or otherwise)

In 4D, truthy and falsy evaluation reflects the usability of a value, which means that a truthy value exists and can be processed by the code without generating errors or unexpected results. The rationale behind this is to provide a convenient way to handle undefined and null values in objects and collections, so that a reduced number of If… Else statements are necessary to avoid runtime errors.

For example, when you use a short-circuit OR operator:

``\$value:=\$object.value || \$defaultValue``

... you get the default value whenever \$object does not contain the `value` property OR when it is null. So this operator checks the existence or usability of the value instead of a specific value. Note that because the numerical value 0 exists and is usable, it is not treated specially, thus it is truthy.

Regarding values representing collections, objects, or strings, "empty" values are considered falsy. It is handy when you want to assign a default value whenever an empty one is encountered.

``\$phone:=\$emp.phone || "n/a"``