Pular para o conteúdo principal

Variáveis

Aprenda sobre variáveis em Dart.

Aqui está um exemplo de criação de uma variável e inicialização dela:

dart
var name = 'Bob';

Variáveis armazenam referências. A variável chamada name contém uma referência a um objeto String com o valor "Bob".

O tipo da variável name é inferido como String, mas você pode mudar esse tipo especificando-o. Se um objeto não está restrito a um único tipo, especifique o tipo Object (ou dynamic, se necessário).

dart
Object name = 'Bob';

Outra opção é declarar explicitamente o tipo que seria inferido:

dart
String name = 'Bob';

Null safety

#

A linguagem Dart impõe sound null safety.

Null safety previne um erro que resulta do acesso não intencional a variáveis definidas como null. O erro é chamado de null dereference error. Um null dereference error ocorre quando você acessa uma propriedade ou chama um método em uma expressão que avalia para null. Uma exceção a essa regra é quando null suporta a propriedade ou o método, como toString() ou hashCode. Com null safety, o compilador Dart detecta esses erros potenciais em tempo de compilação.

Por exemplo, suponha que você queira encontrar o valor absoluto de uma variável int i. Se i for null, chamar i.abs() causa um null dereference error. Em outras linguagens, tentar isso pode levar a um erro em tempo de execução. O compilador do Dart evita esse erro proibindo essas ações.

Null safety introduz três mudanças principais:

  1. Quando você especifica um tipo para uma variável, parâmetro ou outro componente relevante, você pode controlar se o tipo permite null. Para habilitar nullability, você adiciona um ? ao final da declaração de tipo.

    dart
    String? name  // Nullable type. Can be `null` or string.
    ​
    String name   // Non-nullable type. Cannot be `null` but can be string.
    
  2. Você deve inicializar variáveis antes de usá-las. Variáveis nullable têm como padrão null, então elas são inicializadas por padrão. Dart não define valores iniciais para tipos não-nullable. Ele força você a definir um valor inicial. Dart não permite que você observe uma variável não inicializada. Isso impede que você acesse propriedades ou chame métodos quando o tipo do receptor pode ser null mas null não suporta o método ou a propriedade usada.

  3. Você não pode acessar propriedades ou chamar métodos em uma expressão com um tipo nullable. A mesma exceção se aplica quando é uma propriedade ou método que null suporta, como hashCode ou toString().

Sound null safety transforma potenciais erros em tempo de execução em erros de análise em tempo de edição. Null safety sinaliza uma variável não-null quando ela foi:

  • Não inicializada com um valor não-null.
  • Atribuída com um valor null.

Essa verificação permite que você corrija esses erros antes de implantar seu app.

Valor padrão

#

Variáveis não inicializadas que têm um tipo nullable têm um valor inicial de null. Até variáveis com tipos numéricos são inicialmente null, porque números—como tudo mais em Dart—são objetos.

dart
int? lineCount;
assert(lineCount == null);

Com null safety, você deve inicializar os valores de variáveis non-nullable antes de usá-las:

dart
int lineCount = 0;

Você não precisa inicializar uma variável local onde ela é declarada, mas precisa atribuir a ela um valor antes de ela ser usada. Por exemplo, o código a seguir é válido porque Dart consegue detectar que lineCount é não-null no momento em que é passada para print():

dart
int lineCount;
​
if (weLikeToCount) {
  lineCount = countLines();
} else {
  lineCount = 0;
}
​
print(lineCount);

Variáveis de nível superior e de classe são inicializadas de forma preguiçosa (lazy); o código de inicialização é executado na primeira vez que a variável é usada.

Variáveis late

#

O modificador late tem dois casos de uso:

  • Declarar uma variável non-nullable que é inicializada após sua declaração.
  • Inicializar uma variável de forma preguiçosa (lazy).

Frequentemente a análise de fluxo de controle do Dart consegue detectar quando uma variável non-nullable recebe um valor non-null antes de ser usada, mas às vezes a análise falha. Dois casos comuns são variáveis de nível superior e variáveis de instância: o Dart frequentemente não consegue determinar se elas foram definidas, então não tenta.

Se você tem certeza de que uma variável é definida antes de ser usada, mas o Dart discorda, você pode corrigir o erro marcando a variável como late:

dart
late String description;
​
void main() {
  description = 'Feijoada!';
  print(description);
}

Quando você marca uma variável como late mas a inicializa em sua declaração, o inicializador é executado na primeira vez que a variável é usada. Essa inicialização preguiçosa é útil em alguns casos:

  • A variável pode não ser necessária, e inicializá-la é custoso.
  • Você está inicializando uma variável de instância, e seu inicializador precisa acessar this.

No exemplo a seguir, se a variável temperature nunca for usada, então a função custosa readThermometer() nunca é chamada:

dart
// This is the program's only call to readThermometer().
late String temperature = readThermometer(); // Lazily initialized.

Final e const

#

Se você nunca pretende mudar uma variável, use final ou const, seja no lugar de var ou além de um tipo. Uma variável final pode ser definida apenas uma vez; uma variável const é uma constante em tempo de compilação. (Variáveis const são implicitamente final.)

Aqui está um exemplo de criação e definição de uma variável final:

dart
final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';

Você não pode mudar o valor de uma variável final:

análise estática: falha dart
name = 'Alice'; // Error: a final variable can only be set once.

Use const para variáveis que você quer que sejam constantes em tempo de compilação. Se a variável const está no nível de classe, marque-a como static const. Onde você declara a variável, defina o valor como uma constante em tempo de compilação, como um número ou string literal, uma variável const, ou o resultado de uma operação aritmética com números constantes:

dart
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere

A keyword const não serve apenas para declarar variáveis constantes. Você também pode usá-la para criar valores constantes, assim como para declarar construtores que criam valores constantes. Qualquer variável pode ter um valor constante.

dart
var foo = const [];
final bar = const [];
const baz = []; // Equivalent to `const []`

Você pode omitir const da expressão de inicialização de uma declaração const, como em baz acima. Para detalhes, veja NÃO use const redundantemente.

Você pode mudar a referência de uma variável não-final e não-const, mesmo que ela tenha tido antes um valor const:

dart
foo = [1, 2, 3]; // Was const []

Você não pode mudar o valor de uma variável const:

análise estática: falha dart
baz = [42]; // Error: Constant variables can't be assigned a value.

Você pode definir constantes que usam verificações e casts de tipo (is e as), if em coleções e operadores spread (... e ...?):

dart
const Object i = 3; // Where i is a const Object with an int value...
const list = [i as int]; // Use a typecast.
const map = {if (i is int) i: 'int'}; // Use is and collection if.
const set = {if (list is List<int>) ...list}; // ...and a spread.

Para mais informações sobre usar const para criar valores constantes, veja Lists, Maps e Classes.

Variáveis wildcard

#

Uma variável wildcard com o nome _ declara uma variável local ou parâmetro que é não-vinculante; essencialmente, um placeholder. O inicializador, se houver, ainda é executado, mas o valor não fica acessível. Múltiplas declarações nomeadas _ podem existir no mesmo namespace sem gerar erro de colisão.

Declarações de nível superior ou membros em que a privacidade da biblioteca pode ser afetada não são usos válidos para variáveis wildcard. Declarações locais a um escopo de bloco, como os exemplos a seguir, podem declarar um wildcard:

  • Declaração de variável local.

    dart
    main() {
      var _ = 1;
      int _ = 2;
    }
    
  • Declaração de variável de loop for.

    dart
    for (var _ in list) {}
    
  • Parâmetros de cláusula catch.

    dart
    try {
      throw '!';
    } catch (_) {
      print('oops');
    }
    
  • Parâmetros de tipo genérico e de tipo de função.

    dart
    class T<_> {}
    void genericFunction<_>() {}
    ​
    takeGenericCallback(<_>() => true);
    
  • Parâmetros de função.

    dart
    Foo(_, this._, super._, void _()) {}
    ​
    list.where((_) => true);
    ​
    void f(void g(int _, bool _)) {}
    ​
    typedef T = void Function(String _, String _);
    

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ê.