2010-09-23 7 views
8

Est-il possible d'avoir des arguments de la fonction mutables en F #, qui permettrait à quelque chose commeF # arguments de la fonction mutable

let mutable i = 9 

let somefun n = n <- 12;() 

somefun i 

(* *not* a real-world example *) 

Je comprends que cela peut être fait de travailler en l'enveloppant dans un type d'enregistrement

type SomeRec = { mutable i: int } 

let ri = { i = 9 } 

let someotherfun r = r.i <- 12;() 

et que cela peut être fait de la même manière pour les membres de la classe. Cependant, même après avoir parcouru toute la spécification de langage F # (oui, je l'ai fait!), Il semble n'y avoir aucune syntaxe pour permettre le premier cas, et le compilateur semble être très mécontent de mon essai. J'espérais qu'il y aurait une sorte d'annotation de type, mais mutable ne peut pas être utilisé dans un tel. Je sais aussi que je ne devrais pas faire ce genre de chose en premier lieu, mais le premier cas (int liaison) et le second (type record) sont sémantiquement identiques, et une telle objection serait valable pour les deux cas également.

Alors je pense qu'il me manque quelque chose ici.

+8

Si vous avez besoin de muter vos paramètres, vous pensez toujours impérativement. Pouvez-vous décrire exactement ce que vous essayez de faire, peut-être que quelqu'un peut suggérer une solution plus idiomatique à la place. – Juliet

Répondre

14

Vous pouvez utiliser ref comme arguments

let v = ref 0 
let mutate r = 
    r := 100 
mutate v 
printfn "%d" !v 

Ou ByRef mot-clé

let mutable v = 0 
let mutate (r : byref<_>) = 
    r <- 100 
mutate &v 
printfn "%d" v 
+3

Notez que 'byref' est comme C#' ref'. Si vous avez besoin de C# 'out', alors utilisez' byref' mais ajoutez aussi l'attribut '[]' au paramètre. – Brian

+3

Cette réponse est techniquement correcte, mais je serais grincer des dents en la voyant utilisée dans la pratique. OP devrait s'en tenir aux idiomes de F # au lieu d'essayer d'écrire C# dans une syntaxe légèrement différente. – Juliet

+3

@Juliet Cela peut être un * lot * plus rapide que l'équivalent fonctionnel en F #. J'ai utilisé ceci dans le code de production. –

8

Utilisez mot-clé qui est byref C# est égal à ref. Voir la section "Passage par référence" au http://msdn.microsoft.com/en-us/library/dd233213.aspx

+0

Oh mon dieu, il me reste des morceaux assez basiques qui me manquent. Je suppose qu'il est de retour à lire le tout * encore une fois *. Désolé, je ne peux que marquer une réponse «acceptée», mais je vais voter pour celle-ci. –

+0

Je viens de trouver l'article de Jon Skeet sur les paramètres passant dans un autre sujet: http://www.yoda.arachsys.com/csharp/parameters.html C'est sur C#, mais c'est exactement ce dont vous avez besoin maintenant. –