Em PowerShell, funções são blocos de código reutilizáveis que podem receber dados de entrada através de parâmetros. Dominar o uso de parâmetros é essencial para criar funções flexíveis e robustas. Nesta aula, exploraremos a declaração de parâmetros com param(), a tipagem para garantir tipos de dados corretos, valores padrão para tornar parâmetros opcionais e a diferença entre passagem posicional e nomeada.

Parâmetros permitem que suas funções se adaptem a diferentes cenários sem modificar o código interno. Compreender esses conceitos elevará a qualidade dos seus scripts, tornando-os mais profissionais e fáceis de manter.

param()

A palavra-chave param() é usada dentro de uma função para declarar seus parâmetros. Ela deve ser a primeira instrução no corpo da função, antes de qualquer outro código. Dentro dos parênteses, você lista os nomes dos parâmetros separados por vírgulas.

Exemplo básico:

function Saudacao {
    param($nome)
    Write-Host "Olá, $nome!"
}

Saudacao -nome "Maria"  # Saída: Olá, Maria!

Você também pode declarar múltiplos parâmetros:

function Soma {
    param($a, $b)
    return $a + $b
}

Soma 3 4  # Saída: 7

Note que, por padrão, os parâmetros são opcionais e do tipo System.Object. Para maior controle, utilizamos atributos e tipagem.

Tipagem

O PowerShell permite especificar o tipo de dado esperado para cada parâmetro, usando a sintaxe [tipo] antes do nome. Isso ajuda a evitar erros e documenta a intenção da função.

Exemplo com tipagem:

function Dividir {
    param([int]$dividendo, [int]$divisor)
    if ($divisor -eq 0) {
        throw "Divisão por zero não permitida"
    }
    return $dividendo / $divisor
}

Dividir 10 3  # Saída: 3 (inteiro, pois resultado é truncado)
Dividir 10.5 2  # Erro: não pode converter double para int

Se o argumento não puder ser convertido para o tipo declarado, o PowerShell gera um erro. Você pode usar tipos como [string], [int], [double], [bool], [datetime], [array], [hashtable], entre outros. Também é possível usar tipos personalizados ou classes .NET.

Valores padrão

Para tornar um parâmetro opcional, você pode atribuir um valor padrão na declaração. Se o usuário não fornecer o argumento, o valor padrão será usado.

Sintaxe: param($parametro = valorPadrao)

function SaudacaoPersonalizada {
    param($nome = "Visitante", $saudacao = "Olá")
    Write-Host "$saudacao, $nome!"
}

SaudacaoPersonalizada  # Saída: Olá, Visitante!
SaudacaoPersonalizada -nome "João"  # Saída: Olá, João!
SaudacaoPersonalizada -saudacao "Bem-vindo" -nome "Ana"  # Saída: Bem-vindo, Ana!

Valores padrão podem ser expressões, como Get-Date ou (Get-Location).Path. Eles são avaliados no momento da chamada da função, a menos que sejam constantes.

Parâmetros posicionais vs nomeados

No PowerShell, você pode passar argumentos para uma função de duas formas: posicional (pela ordem) ou nomeado (especificando o nome do parâmetro).

Parâmetros posicionais: Os argumentos são associados aos parâmetros na ordem em que aparecem na chamada, seguindo a ordem de declaração no param().

function ExemploPosicional {
    param($primeiro, $segundo, $terceiro)
    Write-Host "Primeiro: $primeiro, Segundo: $segundo, Terceiro: $terceiro"
}

ExemploPosicional 1 2 3  # Saída: Primeiro: 1, Segundo: 2, Terceiro: 3

Parâmetros nomeados: Você especifica explicitamente o nome do parâmetro seguido do valor. Isso torna a chamada mais legível e independente da ordem.

ExemploPosicional -terceiro 3 -primeiro 1 -segundo 2  # Saída: Primeiro: 1, Segundo: 2, Terceiro: 3

Você pode misturar ambas as formas, mas é recomendável usar nomeados para evitar confusão quando há muitos parâmetros. O PowerShell prioriza os nomeados; se um parâmetro já foi especificado pelo nome, ele não será preenchido por posição.

Para forçar que parâmetros sejam sempre nomeados, você pode usar o atributo [Parameter(Mandatory)] e definir posição como 0 ou usar ValueFromPipeline. Mas o comportamento padrão já é flexível.

Boas práticas e observações finais

Ao projetar funções, prefira parâmetros nomeados para melhor clareza, especialmente se houver mais de dois parâmetros ou se alguns forem opcionais. Use tipagem sempre que possível para capturar erros cedo. Valores padrão ajudam a reduzir a complexidade para o usuário. Lembre-se de que parâmetros podem ser declarados com atributos avançados, como [Parameter(Mandatory=$true)], [ValidateSet()], [ValidateRange()], que serão vistos em aulas futuras.

Referências

Exercícios

  1. Crie uma função chamada CalcularAreaRetangulo que receba dois parâmetros: largura e altura (ambos do tipo [double]) e retorne a área (largura * altura).

    ✓ Resposta:
    function CalcularAreaRetangulo {
        param([double]$largura, [double]$altura)
        return $largura * $altura
    }
  2. Modifique a função do exercício 1 para que altura tenha valor padrão 1.0. Teste chamando a função apenas com largura.

    ✓ Resposta:
    function CalcularAreaRetangulo {
        param([double]$largura, [double]$altura = 1.0)
        return $largura * $altura
    }
    # Teste:
    CalcularAreaRetangulo 5  # Retorna 5.0
  3. Escreva uma função ExibirInfo que aceite três parâmetros: nome (string), idade (int) e cidade (string). Chame-a usando parâmetros nomeados em ordem diferente da declaração.

    ✓ Resposta:
    function ExibirInfo {
        param([string]$nome, [int]$idade, [string]$cidade)
        Write-Host "$nome, $idade anos, mora em $cidade"
    }
    
    ExibirInfo -cidade "São Paulo" -nome "Carlos" -idade 30
  4. Crie uma função ConcatenarStrings que receba duas strings (a e b) e retorne a concatenação. Use tipagem e valor padrão para b como string vazia.

    ✓ Resposta:
    function ConcatenarStrings {
        param([string]$a, [string]$b = "")
        return $a + $b
    }
    
    ConcatenarStrings "Olá" " Mundo"  # Retorna "Olá Mundo"
    ConcatenarStrings "Teste"  # Retorna "Teste"
  5. Explique a diferença entre passar argumentos posicionalmente e por nome. Dê um exemplo onde o uso posicional pode causar erro se a ordem for trocada.

    ✓ Resposta:Na passagem posicional, a ordem dos argumentos deve corresponder à ordem dos parâmetros na declaração. Se a ordem for trocada, os valores podem ser atribuídos aos parâmetros errados. Por exemplo, em uma função Dividir($a, $b), chamar Dividir 10 2 funciona, mas Dividir 2 10 retornaria 0.2, o que pode não ser o esperado. Já com parâmetros nomeados, a ordem não importa: Dividir -b 2 -a 10 sempre retorna 5.