我知道在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
答案 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?
}