Pular para o conteúdo principal

Operadores

Aprenda sobre os operadores que Dart suporta.

Dart suporta os operadores mostrados na tabela a seguir. A tabela mostra a associatividade de operadores do Dart e precedência de operadores do mais alto ao mais baixo, que são uma aproximação das relações de operadores do Dart. Você pode implementar muitos desses operadores como membros de classe.

DescriçãoOperadorAssociatividade
unário pós-fixado expr ++ expr -- () [] ?[] . ?. ! Nenhuma
unário prefixado - expr ! expr ~ expr ++ expr -- expr await expr Nenhuma
multiplicativo * / % ~/ Esquerda
aditivo+ -Esquerda
deslocamento << >> >>> Esquerda
AND bit a bit&Esquerda
XOR bit a bit^Esquerda
OR bit a bit|Esquerda
relacional e teste de tipo >= > <= < as is is! Nenhuma
igualdade== !=Nenhuma
AND lógico&&Esquerda
OR lógico||Esquerda
se-nulo??Esquerda
condicional expr1 ? expr2 : expr3 Direita
cascata.. ?..Esquerda
atribuição = *= /= += -= &= ^= etc. Direita
spread (Veja nota) ... ...? Nenhuma

Quando você usa operadores, você cria expressões. Aqui estão alguns exemplos de expressões de operadores:

dart
a++
a + b
a = b
a == b
c ? a : b
a is T

Exemplo de precedência de operadores

#

Na tabela de operadores, cada operador tem precedência maior que os operadores nas linhas que o seguem. Por exemplo, o operador multiplicativo % tem precedência maior que (e portanto executa antes) o operador de igualdade ==, que tem precedência maior que o operador AND lógico &&. Essa precedência significa que as duas linhas de código a seguir executam da mesma forma:

dart
// Parentheses improve readability.
if ((n % i == 0) && (d % i == 0)) {
  // ...
}
​
// Harder to read, but equivalent.
if (n % i == 0 && d % i == 0) {
  // ...
}

Operadores aritméticos

#

Dart suporta os operadores aritméticos usuais, conforme mostrado na tabela a seguir.

OperadorSignificado
+Adicionar
-Subtrair
-expr Menos unário, também conhecido como negação (inverter o sinal da expressão)
*Multiplicar
/Dividir
~/Dividir, retornando um resultado inteiro
%Obter o resto de uma divisão inteira (módulo)

Exemplo:

dart
assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5); // Result is a double
assert(5 ~/ 2 == 2); // Result is an int
assert(5 % 2 == 1); // Remainder
​
assert('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');

Dart também suporta operadores de incremento e decremento tanto prefixados quanto pós-fixados.

OperadorSignificado
++var var = var + 1 (valor da expressão é var + 1 )
var++ var = var + 1 (valor da expressão é var )
--var var = var - 1 (valor da expressão é var - 1 )
var-- var = var - 1 (valor da expressão é var )

Exemplo:

dart
int a;
int b;
​
a = 0;
b = ++a; // Increment a before b gets its value.
assert(a == b); // 1 == 1
​
a = 0;
b = a++; // Increment a after b gets its value.
assert(a != b); // 1 != 0
​
a = 0;
b = --a; // Decrement a before b gets its value.
assert(a == b); // -1 == -1
​
a = 0;
b = a--; // Decrement a after b gets its value.
assert(a != b); // -1 != 0

Operadores de igualdade e relacionais

#

A tabela a seguir lista os significados dos operadores de igualdade e relacionais.

OperadorSignificado
==Igual; veja discussão abaixo
!=Não igual
>Maior que
<Menor que
>=Maior ou igual a
<=Menor ou igual a

Para testar se dois objetos x e y representam a mesma coisa, use o operador ==. (No caso raro onde você precisa saber se dois objetos são exatamente o mesmo objeto, use a função identical() em vez disso.) Aqui está como o operador == funciona:

  1. Se x ou y for null, retorne true se ambos forem null, e false se apenas um for null.

  2. Retorne o resultado de invocar o método == em x com o argumento y. (Isso mesmo, operadores como == são métodos que são invocados em seu primeiro operando. Para detalhes, veja Operadores.)

Aqui está um exemplo de uso de cada um dos operadores de igualdade e relacionais:

dart
assert(2 == 2);
assert(2 != 3);
assert(3 > 2);
assert(2 < 3);
assert(3 >= 3);
assert(2 <= 3);

Operadores de teste de tipo

#

Os operadores as, is e is! são úteis para verificar tipos em tempo de execução.

OperadorSignificado
as Typecast (também usado para especificar prefixos de biblioteca )
isTrue se o objeto tem o tipo especificado
is!True se o objeto não tem o tipo especificado

O resultado de obj is T é true se obj implementa a interface especificada por T. Por exemplo, obj is Object? é sempre true.

Use o operador as para converter um objeto para um tipo específico se e somente se você tiver certeza de que o objeto é desse tipo. Exemplo:

dart
(employee as Person).firstName = 'Bob';

Se você não tiver certeza de que o objeto é do tipo T, então use is T para verificar o tipo antes de usar o objeto.

dart
if (employee is Person) {
  // Type check
  employee.firstName = 'Bob';
}

Operadores de atribuição

#

Como você já viu, você pode atribuir valores usando o operador =. Para atribuir apenas se a variável atribuída for null, use o operador ??=.

dart
// Assign value to a
a = value;
// Assign value to b if b is null; otherwise, b stays the same
b ??= value;

Operadores de atribuição composta como += combinam uma operação com uma atribuição.

= *= %= >>>= ^=
+= /= <<= &= |=
-=~/=>>=

Aqui está como os operadores de atribuição composta funcionam:

Atribuição compostaExpressão equivalente
Para um operador op: a op= b a = a op b
Exemplo:a += ba = a + b

O exemplo a seguir usa operadores de atribuição e atribuição composta:

dart
var a = 2; // Assign using =
a *= 3; // Assign and multiply: a = a * 3
assert(a == 6);

Operadores lógicos

#

Você pode inverter ou combinar expressões booleanas usando os operadores lógicos.

OperadorSignificado
!expr inverte a expressão seguinte (muda false para true, e vice-versa)
||OR lógico
&&AND lógico

Aqui está um exemplo de uso dos operadores lógicos:

dart
if (!done && (col == 0 || col == 3)) {
  // ...Do something...
}

Operadores bit a bit e de deslocamento

#

Você pode manipular os bits individuais de números em Dart. Normalmente, você usaria esses operadores bit a bit e de deslocamento com inteiros.

OperadorSignificado
&AND
|OR
^XOR
~expr Complemento bit a bit unário (0s se tornam 1s; 1s se tornam 0s)
<<Deslocar à esquerda
>>Deslocar à direita
>>>Deslocamento à direita sem sinal

Aqui está um exemplo de uso de operadores bit a bit e de deslocamento:

dart
final value = 0x22;
final bitmask = 0x0f;
​
assert((value & bitmask) == 0x02); // AND
assert((value & ~bitmask) == 0x20); // AND NOT
assert((value | bitmask) == 0x2f); // OR
assert((value ^ bitmask) == 0x2d); // XOR
​
assert((value << 4) == 0x220); // Shift left
assert((value >> 4) == 0x02); // Shift right
​
// Shift right example that results in different behavior on web
// because the operand value changes when masked to 32 bits:
assert((-value >> 4) == -0x03);
​
assert((value >>> 4) == 0x02); // Unsigned shift right
assert((-value >>> 4) > 0); // Unsigned shift right

Expressões condicionais

#

Dart tem dois operadores que permitem avaliar concisamente expressões que de outra forma poderiam exigir instruções if-else:

condition ? expr1 : expr2

Se condition for true, avalia expr1 (e retorna seu valor); caso contrário, avalia e retorna o valor de expr2.

expr1 ?? expr2

Se expr1 for não-null, retorna seu valor; caso contrário, avalia e retorna o valor de expr2.

Quando você precisa atribuir um valor baseado em uma expressão booleana, considere usar o operador condicional ? e :.

dart
var visibility = isPublic ? 'public' : 'private';

Se a expressão booleana testa para null, considere usar o operador se-nulo ?? (também conhecido como operador de coalescência nula).

dart
String playerName(String? name) => name ?? 'Guest';

O exemplo anterior poderia ter sido escrito de pelo menos duas outras formas, mas não tão concisamente:

dart
// Slightly longer version uses ?: operator.
String playerName(String? name) => name != null ? name : 'Guest';
​
// Very long version uses if-else statement.
String playerName(String? name) {
  if (name != null) {
    return name;
  } else {
    return 'Guest';
  }
}

Notação de cascata

#

Cascatas (.., ?..) permitem que você faça uma sequência de operações no mesmo objeto. Além de acessar membros de instância, você também pode chamar métodos de instância nesse mesmo objeto. Isso frequentemente economiza a etapa de criar uma variável temporária e permite que você escreva código mais fluido.

Considere o código a seguir:

dart
var paint = Paint()
  ..color = Colors.black
  ..strokeCap = StrokeCap.round
  ..strokeWidth = 5.0;

O construtor, Paint(), retorna um objeto Paint. O código que segue a notação de cascata opera neste objeto, ignorando quaisquer valores que possam ser retornados.

O exemplo anterior é equivalente a este código:

dart
var paint = Paint();
paint.color = Colors.black;
paint.strokeCap = StrokeCap.round;
paint.strokeWidth = 5.0;

Se o objeto no qual a cascata opera pode ser null, então use uma cascata null-shorting (?..) para a primeira operação. Começar com ?.. garante que nenhuma das operações de cascata seja tentada naquele objeto null.

dart
document.querySelector('#confirm') // Get an object.
  ?..textContent =
      'Confirm' // Use its members.
  ..classList.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'))
  ..scrollIntoView();

O código anterior é equivalente ao seguinte:

dart
final button = document.querySelector('#confirm');
button?.textContent = 'Confirm';
button?.classList.add('important');
button?.onClick.listen((e) => window.alert('Confirmed!'));
button?.scrollIntoView();

Você também pode aninhar cascatas. Por exemplo:

dart
final addressBook =
    (AddressBookBuilder()
          ..name = 'jenny'
          ..email = 'jenny@example.com'
          ..phone =
              (PhoneNumberBuilder()
                    ..number = '415-555-0100'
                    ..label = 'home')
                  .build())
        .build();

Tenha cuidado para construir sua cascata em uma função que retorna um objeto real. Por exemplo, o código a seguir falha:

dart
var sb = StringBuffer();
sb.write('foo')
  ..write('bar'); // Error: method 'write' isn't defined for 'void'.

A chamada sb.write() retorna void, e você não pode construir uma cascata em void.

Operadores spread

#

Operadores spread avaliam uma expressão que produz uma coleção, desempacotam os valores resultantes e os inserem em outra coleção.

O operador spread não é realmente uma expressão de operador. A sintaxe .../...? faz parte do próprio literal de coleção. Então, você pode aprender mais sobre operadores spread na página Coleções.

Porque não é um operador, a sintaxe não tem nenhuma "precedência de operadores". Efetivamente, ela tem a "precedência" mais baixa — qualquer tipo de expressão é válido como alvo spread, como:

dart
[...a + b]

Outros operadores

#

Você viu a maioria dos operadores restantes em outros exemplos:

OperadorNomeSignificado
()Aplicação de funçãoRepresenta uma chamada de função
[] Acesso de subscrito Representa uma chamada ao operador [] sobrescrevível; exemplo: fooList[1] passa o int 1 para fooList para acessar o elemento no índice 1
?[] Acesso de subscrito condicional Como [] , mas o operando mais à esquerda pode ser null; exemplo: fooList?[1] passa o int 1 para fooList para acessar o elemento no índice 1 a menos que fooList seja null (caso em que a expressão avalia para null)
. Acesso de membro Refere-se a uma propriedade de uma expressão; exemplo: foo.bar seleciona a propriedade bar da expressão foo
?. Acesso de membro condicional Como . , mas o operando mais à esquerda pode ser null; exemplo: foo?.bar seleciona a propriedade bar da expressão foo a menos que foo seja null (caso em que o valor de foo?.bar é null)
! Operador de asserção não-nulo Converte uma expressão para seu tipo não-nulo subjacente, lançando uma exceção em tempo de execução se a conversão falhar; exemplo: foo!.bar afirma que foo é não-null e seleciona a propriedade bar , a menos que foo seja null (caso em que uma exceção em tempo de execução é lançada)

Para mais informações sobre os operadores ., ?. e .., veja Classes.

Encontrou essa página sem tradução ou que precisa de correção? Abra uma issue e nos ajude a manter esse site em PT-BR para ajudar pessoas como você.