我怎么用F#或其他功能语言写这个

时间:2010-03-09 11:18:38

标签: f#

我知道在F#中你分配变量时声明变量。我敢肯定你可以用C语言声明变量,但我怎么写这个

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

3 个答案:

答案 0 :(得分:8)

首先,我不确定你的例子中是否需要任何循环。您的代码始终返回第一行中的值。我会稍微复杂一下这个例子,并假设您可能不希望得到某些ID(因此您可能需要进行一些循环)。

在函数式语言中编写循环结构的常用方法是使用递归(在许多情况下,您可以避免显式使用递归,因为有许多有用的高阶函数可以直接使用)。在这种情况下,您可以编写一个简单的递归函数read,该函数调用r.Read()一次 - 如果成功则返回ID,否则,它会递归调用自身以读取下一行:

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() )

read函数在初始化id值的作用域中写为本地函数。这意味着当F#将值赋给id时,它将运行ExecuteReader然后运行本地函数read(这是将初始化写为单个表达式的一种方法)。当然,如Jon建议的那样编写fetchId函数可能更具可读性(在F#中,你将再次使用递归):

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()

答案 1 :(得分:3)

粗略翻译:

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
)
// ...

答案 2 :(得分:2)

理想情况下,您将编写一个单独的函数并从该函数返回值。所以在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?   
}