2010-03-09 4 views
0

Je sais que dans F # vous déclarez des variables quand vous les affectez. Je suis sûr que vous pouvez déclarer vars de manière C mais comment pourrais-je écrire ceComment j'écrirais ceci en F # ou un autre langage fonctionnel

long id=0 
using (SQLiteDataReader r = command.ExecuteReader()) 
{ 
    while (r.Read()) 
    { 
     id = r.GetInt64(0); 
     //... 
     break; 
    } 
} 
//use id in sqlite now that it isnt locked 

Répondre

8

Tout d'abord, je ne sais pas si vous avez besoin d'une boucle dans votre exemple du tout. Votre code renvoie toujours la valeur de la première ligne. Je vais compliquer un peu l'exemple et supposer que vous ne voudrez peut-être pas obtenir certains identifiants comme résultat (vous devrez peut-être faire une boucle). La méthode habituelle pour écrire des constructions en boucle dans les langages fonctionnels est d'utiliser la récursivité (dans de nombreux cas, vous pouvez éviter d'utiliser explicitement la récurrence, car il existe de nombreuses fonctions utiles d'ordre supérieur que vous pouvez utiliser directement). Dans ce cas, vous pouvez écrire une fonction récursive simple, read qui appelle r.Read() une fois - si elle réussit alors il renvoie l'ID, sinon, il s'appelle récursivement lire la ligne suivante:

let id = 
    (use r = command.ExecuteReader() 
    let rec read() = 
     if r.Read() then 
     let id = r.GetInt64(0) 
     if weWantThisId id then id // this is the ID we want 
     else read()     // continue reading IDs 
     else 0      // default value/throw 
    read()) 

La fonction read est écrit en tant que fonction locale dans une étendue qui initialise la valeur id. Cela signifie que lorsque F # affecte une valeur à id, il exécute ExecuteReader, puis exécute la fonction locale read (c'est une manière d'écrire l'initialisation en tant qu'expression unique). Bien sûr, il peut être plus facile à lire pour écrire une fonction fetchId comme Jon suggère (en F #, vous utiliserez à nouveau récursivité):

let fetchId() = 
    use r = command.ExecuteReader() 
    let rec read() = 
    if r.Read() then 
     let id = r.GetInt64(0) 
     if weWantThisId id then id 
     else read() 
    else 0 
    read() 
+0

Qu'en est-il d'appeler Dispose sur 'r'? – Gabe

+0

Il manquait une ligne dans le second extrait, ce qui a probablement causé de la confusion. Quoi qu'il en soit, j'utilise 'use', donc' r' sera automatiquement éliminé quand il est hors de portée (après avoir calculé l'ID dans le premier exemple ou après avoir retourné la fonction dans le second exemple). –

+0

parfait, le premier exemple a répondu à ma question. En fait la raison pour laquelle mon code a une boucle et une rupture est bc il y a un si (cond) continue dedans et l'instruction cond (qui n'a pas de sens dans sa propre fonction). J'aime cette capacité à assigner des variables dans une instruction if qui a sa propre portée. –

2

Idéalement, vous écririez une fonction distincte et renvoie la valeur de cette fonction. Donc, en C#:

long id = FetchId(); 

... 

int FetchId(...) 
{ 
    using (SQLiteDataReader r = command.ExecuteReader()) 
    { 
     if (r.Read()) 
     { 
      return r.GetInt64(0); 
     } 
    } 
    // Work out what you want to do if there were no results... 
    // Throw an exception? Change it to a nullable int and return null? 
} 
3

traduction approximative:

let mutable id = 0L 
(
    use r = command.ExecuteReader() 
    let mutable finished = false 
    while not(finished) do 
     if r.Read() then 
      id <- r.GetInt64(0) 
      // ... 
      finished <- true 
     else 
      finished <- true 
) 
// ... 
+0

Utilisez une variable mutable réelle (non disponible dans toutes les langues fonctionnelles, mais disponible en F #), la réponse la plus littéralement correcte à la question posée, je suppose. – peSHIr

Questions connexes