Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
As declarações exigíveis, ou exigíveis, declaradas num âmbito global são publicamente visíveis por defeito; ou seja, eles podem ser usados em qualquer lugar no mesmo projeto e em um projeto que faça referência à montagem em que são declarados. modificadores do Access permitir que você restrinja sua visibilidade apenas ao assembly atual, de modo que os detalhes da implementação possam ser alterados posteriormente sem interromper o código que depende de uma biblioteca específica.
Q# suporta dois tipos de chamadas: operações e funções. O tópico Operações e Funções elabora a distinção entre os dois. Q# também suporta a definição de modelos ; por exemplo, implementações parametrizadas por tipo para um determinado chamável. Para obter mais informações, consulte parametrizações de tipo.
Observação
Tais implementações parametrizadas de tipo não podem usar construções de linguagem que dependam de propriedades particulares dos argumentos de tipo; Atualmente, não há como expressar restrições de tipo no Q#ou definir implementações especializadas para argumentos de tipo específicos.
Chamáveis e functores
Q# permite implementações especializadas para fins específicos; Por exemplo, as operações no Q# podem definir implícita ou explicitamente o suporte para determinados functors e, junto com ele, as implementações especializadas a serem invocadas quando um functor específico é aplicado a esse chamável.
Um functor, em certo sentido, é uma fábrica que define uma nova implementação chamável que tem uma relação específica com o chamável ao qual foi aplicado. Os functors são mais do que as funções tradicionais de nível superior, na medida em que requerem acesso aos detalhes de implementação do chamável ao qual foram aplicados. Nesse sentido, eles são semelhantes a outras fábricas, como modelos. Eles também podem ser aplicados a chamadas parametrizadas por tipo.
Considere a seguinte operação, ApplyQFT:
operation ApplyQFT(qs : Qubit[]) : Unit is Adj + Ctl {
let length = Length(qs);
Fact(length >= 1, "ApplyQFT: Length(qs) must be at least 1.");
for i in length - 1..-1..0 {
H(qs[i]);
for j in 0..i - 1 {
Controlled R1Frac([qs[i]], (1, j + 1, qs[i - j - 1]));
}
}
}
Esta operação usa um argumento do tipo Qubit[] e retorna um valor do tipo Unit. A anotação is Adj + Ctl na declaração de ApplyQFT indica que a operação suporta tanto o Adjoint quanto o functor Controlled. (Para obter mais informações, consulte Características da operação). A expressão Adjoint ApplyQFT acessa a especialização que implementa o adjunto de ApplyQFTe Controlled ApplyQFT acessa a especialização que implementa a versão controlada de ApplyQFT.
Além do argumento da operação original, a versão controlada de uma operação usa uma matriz de qubits de controle e aplica a operação original na condição de que todos esses qubits de controle estejam em um estado |1⟩.
Em teoria, uma operação para a qual uma versão adjunta pode ser definida também deve ter uma versão controlada e vice-versa. Na prática, no entanto, pode ser difícil desenvolver uma implementação para um ou outro, especialmente para implementações probabilísticas seguindo um padrão de repetição até o sucesso. Por esse motivo, Q# permite que você declare apoio para cada functor individualmente. No entanto, como os dois functors se deslocam, uma operação que define o suporte para ambos também tem que ter uma implementação (geralmente implicitamente definida, significando compilador-gerado) para quando ambos os functors são aplicados à operação.
Não existem functores que possam ser aplicados a funções. Atualmente, as funções têm exatamente uma implementação de corpo e não há mais especializações. Por exemplo, a declaração
function Hello (name : String) : String {
$"Hello, {name}!"
}
é equivalente a
function Hello (name : String) : String {
body ... {
$"Hello, {name}!"
}
}
Aqui, body especifica que a implementação dada se aplica ao corpo padrão da função Hello, o que significa que a implementação é invocada quando nenhum functor ou outros mecanismos de fábrica foram aplicados antes da invocação. Os três pontos em body ... correspondem a uma diretiva de compilador indicando que os itens de argumento na declaração de função devem ser copiados e colados neste local.
As razões por trás de indicar explicitamente onde os argumentos da declaração chamável pai devem ser copiados e colados são duas: uma, é desnecessário repetir a declaração de argumento, e duas, garante que os functores que exigem argumentos adicionais, como o functor Controlled, possam ser introduzidos de maneira consistente.
Quando há exatamente uma especialização definindo a implementação do corpo padrão, o encapsulamento adicional do formulário body ... { <implementation> } pode ser omitido.
Recursão
Q# convocáveis podem ser direta ou indiretamente recursivas e podem ser declaradas em qualquer ordem; Uma operação ou função pode chamar-se a si mesma, ou pode chamar outro chamável que direta ou indiretamente chama o chamador.
O espaço da pilha pode ser limitado quando executado em hardware quântico, e as recursões que excedem esse limite de espaço da pilha resultam em um erro de tempo de execução.