Pergunta

Bem, eu vim a entender que o F# é capaz de gerenciar referências (algum tipo de C++ como referências).Isso permite que as possibilidades para alterar o valor dos parâmetros passados em funções e também permite que o programador para retornar mais de um valor único.No entanto, aqui está o que eu preciso saber:

  1. Ref palavra-chave:A palavra-chave ref é usado para criar, a partir de um valor, uma referência para que o valor do tipo inferido.Então,

    let myref = ref 10
    

    Isto significa que F# vai criar um objeto do tipo Ref<int> colocando ali (no campo mutável) meu int 10.

    OK.Então, eu suponho que ref é usado para criar instâncias de Ref<'a> escreva.É correto?

  2. O acesso de valor:Para acessar o valor armazenado na referência que eu posso fazer isso:

    let myref = ref 10
    let myval = myref.Value
    let myval2 = !myref
    

    Enquanto o := operador só me permite editar o valor como este:

    let myref = ref 10
    myref.Value <- 30
    myref := 40
    

    Então, ! (Bang) cancela a minha referência.E := editá-lo.Eu suponho que isso é correto também.

  3. O operador&:O que faz este operador faz?É para ser aplicado a um tipo de referência?Não, eu acho que deve ser aplicado para um mutável o valor e este devolve o que?A referência?O endereço?Se utilizar interativo:

    let mutable mutvar = 10;;
    &a;;
    

    A última linha lança um erro, então eu não entendo o que o & o operador é para.

  4. ByRef:O que sobre byref?Isso é muito importante para mim, mas eu percebo que eu não entendo isso.Eu entendo que é usada na função sobre a passagem de parâmetro.Usa byref quando ele quer que o valor passado podem ser editados (este é um pouco contra a linguagem funcional' da filosofia, mas f# é algo mais do que isso).Considere o seguinte:

    let myfunc (x: int byref) =
        x <- x + 10
    

    Isso é estranho.Eu sei que se você tiver uma referência let myref = ref 10 e, em seguida, fazer isso para editar o valor: myref <- 10 surge um erro, porque ele deve ser como este: myref := 10.No entanto, o fato de que, na função que eu possa editar x usando o <- operador de meios que x não é uma referência, né?

    Se eu assumir que x não é uma referência, então eu suponho também que, em exercício de funções, quando utilizar byref em um parâmetro, o parâmetro pode ter o mutável sintaxe aplicada.Então é apenas uma questão de sintaxe, se eu assumir isso eu estou OK, e, na verdade, tudo funciona (sem erros de compilador).No entanto, o que é x?

  5. Funções de chamada:Como posso usar uma função utilizando parâmetros byref?

    O & o operador está envolvido, mas você poderia explicar isso melhor, por favor?Neste artigo: MSDN Parâmetros e Argumentos o exemplo a seguir é fornecido:

    type Incrementor(z) =
        member this.Increment(i : int byref) =
           i <- i + z
    
    let incrementor = new Incrementor(1)
    let mutable x = 10
    // A: Not recommended: Does not actually increment the variable. (Me: why?)
    incrementor.Increment(ref x)
    // Prints 10.
    printfn "%d" x  
    
    let mutable y = 10
    incrementor.Increment(&y) (* Me: & what does it return? *)
    // Prints 11.
    printfn "%d" y 
    
    let refInt = ref 10
    incrementor.Increment(refInt) (* Why does it not work in A, but here it does? *)
    // Prints 11.
    printfn "%d" !refInt
    
Foi útil?

Solução

Ref palavra-chave Sim, quando você escrever let a = ref 10 você está essencialmente escrita let a = new Ref<int>(10) onde o Ref<T> tipo tem um campo mutável Value.

O acesso de valor O := e ! os operadores são apenas atalhos para escrever:

a.Value <- 10  // same as writing: a := 10
a.Value        // same as writing: !a

ByRef é um tipo especial que pode ser (razoavelmente) usado apenas em parâmetros de método.Isso significa que o argumento deve ser, essencialmente, um ponteiro para algum local de memória (alocado na pilha ou stack).Ele corresponde a out e ref modificadores em C#.Observe que você não pode criar variáveis locais deste tipo.

O operador & é uma forma de criar um valor (um ponteiro) que pode ser passado como um argumento para uma função/método esperando um byref escreva.

Funções de chamada o exemplo com byref funciona porque você está passando o método de uma referência a um local mutável variável.Através da referência, o método pode alterar o valor armazenado na variável.

A seguir não funciona:

let a = 10            // Note: You don't even need 'mutable' here
bar.Increment(ref a)  

A razão é que você está criando uma nova instância de Ref<int> e você está copiando o valor de a para este exemplo.O Increment método, em seguida, modifica o valor armazenado na pilha na instância de Ref<int>, mas você não tem uma referência a esse objeto.

let a = ref 10
bar.Increment(a)  

Isso funciona, porque a é um valor do tipo Ref<int> e você está passando um ponteiro para a pilha atribuídos instância para Increment e, em seguida, obter o valor da pilha atribuídos a referência de célula usando !a.

(Você pode usar valores criados usando ref como argumentos para byref porque o compilador processa este caso especialmente - ele será automaticamente tomar referência do Value campo porque este é um cenário útil...).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top