我是f#世界的新手。我写了一个非常小的应用程序,它从sap查询数据并将结果显示为输出。当应用程序尝试连接sap时,如果出现问题,可能会抛出一些异常。
请看以下代码:
type Customer() =
let mutable _lastName = String.Empty
member self.LastName with get () = _lastName
member self.QueryData () =
//Some CODES here
let bapi = SapBapi()
let bapiFunc = bapi.GetBapiFunc(dest, "BAPI_CUSTOMER_GETDETAIL1")
match bapiFunc with
| Success bp ->
//Some CODES here
let addressData = bp.GetStructure("PE_PERSONALDATA")
_lastName <- addressData.GetString("LASTNAME")
None
| RfcCommunication ex ->
Some(ex :> Exception)
| RfcLogon ex ->
Some(ex :> Exception)
| RfcAbapRuntime ex ->
Some(ex :> Exception)
正如您所看到的,我使用选项类型处理错误,并将抛出的异常向下转换为基本异常类型。
在主要功能
中open CustomerBapi
open System
[<EntryPoint>]
let main argv =
let customer = CustomerBapi.Customer()
let ex = customer.QueryData()
match ex with
| Some ex ->
printfn "%s" ex.Message
| None ->
printfn "%s" customer.LastName
Console.ReadLine() |> ignore
0 // return an integer exit code
此代码有效,但我是否以正确的方式处理异常?
我在网上看过一篇文章,在f#中处理异常应该返回一个错误代码,它比异常风格更容易。
答案 0 :(得分:2)
在类型系统中处理错误的典型方法是使用Either
类型。
type Either<'a,'b> =
| Left of 'a
| Right of 'b
传统上,Right值带有成功结果,Left带有错误或异常(作为string
或exc
类型)。考虑它的一种简单方法是将其视为option
,其中Right
对应于Some
个案,而不是None
您有错误信息。
所以你的代码可能变成:
// QueryData no longer needs to depend on side effects to work,
//so you can make it a regular function instead of a method
let result = queryData()
match result with
| Left ex ->
// handle exception
printfn "%s" ex.Message
| Right result ->
// either set the property, or make customer a record
// and set the name field here
customer.LastName <- result
printfn "%s" customer.LastName
关于错误代码的一点听起来非常错误,想知道你在哪里找到它。
答案 1 :(得分:0)
总的来说,我认为您的解决方案没问题,但可以改进 您在代码中混合了功能和OO样式。对于我来说,使用异常作为唯一可选值感觉有点奇怪。通常,客户应该是包含可选性的值,并且如果客户具有值,则匹配应该是。