As chaves representam parâmetros nomeados opcionais.
Exemplo:
void foo(int a, {int b, int c}) { /* alguma ação */ }
Dessa forma, você estaria falando que o a
é um parâmetro obrigatório e o b
e c
são opcionais.
Para chamar essa função poderia fazer:
foo(1, c: 3, b: 2);
// a = 1; b = 2; c = 3;
// Perceba que os parâmetros podem estar fora de ordem.
foo(1, c: 2)
// a = 1; b = null; c = 2;
foo(1)
// a = 1; b = null; c = null;
Também existem parâmetros posicionais opcionais, mas como isso foge do escopo da pergunta eu vou deixar pra você procurar.
O @required
transforma um parâmetro nomeado opcional em parâmetro nomeado obrigatório.
Vamos comparar essas duas funções:
const SnackBarAction({
Key key,
this.textColor,
this.disabledTextColor,
@required this.label,
@required this.onPressed,
}) : assert(label != null),
assert(onPressed != null),
super(key: key);
const Duration(
{int days = 0,
int hours = 0,
int minutes = 0,
int seconds = 0,
int milliseconds = 0,
int microseconds = 0})
: this._microseconds(microsecondsPerDay * days +
microsecondsPerHour * hours +
microsecondsPerMinute * minutes +
microsecondsPerSecond * seconds +
microsecondsPerMillisecond * milliseconds +
microseconds);
No Duration
nós podemos simplesmente chamar Duration()
sem colocar nenhum parâmetro, por causa da ausência do @required
. Já no SnackBarAction
você é obrigado a colocar pelo menos dois parâmetros, sendo eles: label
e onPressed
.
SnackBarAction(label: 'Botão', onPressed: () { /* alguma ação */ })
O super
chama uma função da classe que ele herdou. Se foi simplesmente super
, ele irá chamar o construtor. Se for super.foo
, ele vai chamar a função foo da classe de que ele herdou e dentro dos parênteses ele irá passar os parâmetros.
Detalhes({Key key, @required this.receita}) : super(key: key);
Então, nessa função ele está chamando o construtor da classe que ele herdou. O
key:
em super
representa o nome do parâmetro e o segundo key
é igual ao parâmetro key
de Detalhes
.