如何处理异常输入并停止在F#中运行函数的其余部分?
我一直在学习F#,我正在用它写一个工具。除了我需要处理无效输入或异常情况外,一切正常 在F#中,推荐的处理方法是什么?根据我的函数的构造和使用方式,我不确定如何发回一条消息,告诉调用函数调用失败是由于输入错误,类似于C#的循环continue需要发生 我因失去归宿而痛苦。我可以从F#函数的任意位置返回,还是必须在最后一行 这里是我的一些代码的一个例子,其中输入在某些情况下基本上是空的,我正在检测到这一点。我需要防止流程中随后的步骤运行如何处理异常输入并停止在F#中运行函数的其余部分?,f#,F#,我一直在学习F#,我正在用它写一个工具。除了我需要处理无效输入或异常情况外,一切正常 在F#中,推荐的处理方法是什么?根据我的函数的构造和使用方式,我不确定如何发回一条消息,告诉调用函数调用失败是由于输入错误,类似于C#的循环continue需要发生 我因失去归宿而痛苦。我可以从F#函数的任意位置返回,还是必须在最后一行 这里是我的一些代码的一个例子,其中输入在某些情况下基本上是空的,我正在检测到这一点。我需要防止流程中随后的步骤运行 let SchemaQueryString s =
let SchemaQueryString s =
let sqsValid s =
let Strcat (x : string) (y : string) = x + ", " + y;
let RecFieldName (x : MeasurementRecord) = x.FieldName;
let mapr = List.map RecFieldName s.MeasurementTypes;
let cores = List.reduce Strcat mapr;
"SELECT ProductionCode, TestTime, " + cores + " FROM " + s.TemplateName + " ORDER BY ProductionCode, TestTime";
match s.MeasurementTypes.Length with
| 0 -> ""
| _ -> sqsValid s;
let TemplateMigration tcs rr =
let sql = SchemaQueryString tcs;
let sqlc = new SqlCommand(sql, QCOld);
let sqldr = sqlc.ExecuteReader();
ignore (sqldr.Read());
...
我需要中止TemplateMigration函数,并在sql变量与“”匹配时立即返回。或者构造某种联合类型,该类型指示无法构造sql查询字符串,因为对于特定情况,无法进行构造
谢谢你的帮助。我正在逐渐了解这种语言,我非常喜欢它,但我正在努力解决它的某些方面,我不知道如何用函数思想取代我关于如何做某事的过程性思想。与其他语言一样,您可以随时返回。插入一个条件,返回坏数据的特殊值(-1,“错误”等),继续处理,否则返回好数据
或者使用F#s。与其他语言一样,您可以随时返回。插入一个条件,返回坏数据的特殊值(-1,“错误”等),继续处理,否则返回好数据
或者在第一次使用函数式语言时使用F#。许多人会误以为一切都是表达式。这意味着使用控制流表达式执行控制流 那么,语句和表达式之间有什么区别呢 语句没有值,即它不是类型的实例。表达式有一个值(即使该值是特殊类型的
单元
,它有一个不表示值的实例()
)
在过程语言中,我们使用语句来控制执行流程,因此:
class Program
{
static void Main(string[] args)
{
string str;
if (DateTime.Now.DayOfWeek == DayOfWeek.Monday)
return;
else if (args.Length >= 2)
str = args[1];
else
str = "Hello";
Console.WriteLine(str);
}
}
这里我们定义了一个string
类型的变量str
,它的值为null
。然后,我们要么忽略它并返回
,如果是星期一,分配参数[1]
(如果可用),要么“Hello”
,否则打印它
当控制流语句只有几行时,这种编程是相当安全的。然而,一旦语句变得超过一页长,或者变得复杂和嵌套,我们就更有可能引入错误,通常是错误
纯函数式语言使用控制流表达式。这意味着if
表达式有一个值!让我们慢慢实现前一个代码示例中的控件。首先让我们来处理分配字符串str
let str =
if args.Length >= 2 then
args.[1]
else
"Hello"
这里我们看到,我们直接将if
表达式的值绑定到str
。if
表达式的两个分支(子表达式)必须计算为字符串类型的实例。我们不能忘记给字符串赋值,因为如果我们尝试,编译器会抛出一个错误
但在很多情况下,我们希望在控制流的不同分支中做不同类型的事情。在我们的例子中,如果是星期一,我们什么都不想做。这就是受歧视工会的力量发挥作用的地方。这些允许我们将异构类型组合成一个整体,保留了基于表达式的语言在各个级别对代码进行类型检查的能力
在本例中,我们不需要创建新的联合类型,因为选项
类型已经包含此功能。因此,我们改写如下:
open System
[<EntryPoint>]
let Main args =
let str =
if DateTime.Now.DayOfWeek = DayOfWeek.Monday then
None
elif args.Length >= 2 then
Some(args.[1])
else
Some("Hello")
match str with
| Some(str) -> Console.WriteLine(str)
| None -> ()
Environment.ExitCode
但是,最好从SchemaQueryString
let SchemaQueryString s =
... // Elided
match s.MeasurementTypes.Length with
| 0 -> None
| _ -> Some(sqsValid s)
在整个代码中“传播”强类型值。当第一次使用函数式语言时,许多人突然想到一切都是表达式。这意味着使用控制流表达式执行控制流
那么,语句和表达式之间有什么区别呢
语句没有值,即它不是类型的实例。表达式有一个值(即使该值是特殊类型的单元
,它有一个不表示值的实例()
)
在过程语言中,我们使用语句来控制执行流程,因此:
class Program
{
static void Main(string[] args)
{
string str;
if (DateTime.Now.DayOfWeek == DayOfWeek.Monday)
return;
else if (args.Length >= 2)
str = args[1];
else
str = "Hello";
Console.WriteLine(str);
}
}
这里我们定义了一个string
类型的变量str
,它的值为null
。然后,我们要么忽略它并返回
,如果是星期一,分配参数[1]
(如果可用),要么“Hello”
,否则打印它
当控制流语句只有几行时,这种编程是相当安全的。然而,一旦语句变得超过一页长,或者变得复杂和嵌套,我们就更有可能引入错误,通常是错误
纯函数式语言使用控制流表达式。这意味着if
表达式有一个值!让我们慢慢实现前一个代码示例中的控件。首先让我们来处理分配字符串str
let str =
if args.Length >= 2 then
args.[1]
else
"Hello"
这里我们看到,我们直接将if
表达式的值绑定到str
。if
表达式的两个分支(子表达式)必须计算为字符串类型的实例。我们不能忘记给字符串赋值,因为如果我们尝试,编译器会抛出一个错误
但似乎有一个
match SchemaQueryString tcs with
| None -> ()
| Some(sql) -> ... // rest of function