F# 以正确的方式处理异常
我对f#world很陌生。我编写了一个非常小的应用程序,可以从sap查询数据并将结果显示为输出。当应用程序尝试连接sap时,可能会抛出一些异常,以防出现问题 请看以下代码:F# 以正确的方式处理异常,f#,F#,我对f#world很陌生。我编写了一个非常小的应用程序,可以从sap查询数据并将结果显示为输出。当应用程序尝试连接sap时,可能会抛出一些异常,以防出现问题 请看以下代码: type Customer() = let mutable _lastName = String.Empty member self.LastName with get () = _lastName member self.QueryData () = //Some CODES he
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)
type Customer()=
让mutable _lastName=String.Empty
成员self.LastName,get()=\u LastName
成员self.QueryData()=
//这里有一些代码
设bapi=SapBapi()
让bapiFunc=bapi.GetBapiFunc(dest,“bapi\u CUSTOMER\u GETDETAIL1”)
将bapiFunc与
|成功bp->
//这里有一些代码
让addressData=bp.GetStructure(“PE_PERSONALDATA”)
_姓氏
一些(例如:>例外)
|RfcLogon ex->
一些(例如:>例外)
|RfcAbapRuntime ex->
一些(例如:>例外)
如您所见,我使用选项类型处理错误,并将抛出的异常向下转换为基本异常类型
在主要功能中
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
opencustomerbapi
开放系统
[]
让主argv=
让customer=CustomerBapi.customer()
设ex=customer.QueryData()
匹配
|一些ex->
打印“%s”例如消息
|无->
printfn“%s”customer.LastName
Console.ReadLine()|>忽略
0//返回整数退出代码
这段代码可以工作,但我是否以正确的方式处理异常
我在互联网上读到一篇文章,在f#中处理异常应该返回一个错误代码,这比异常样式更容易。一般来说,我认为您的解决方案是可以的,但可以改进。
在代码中混合了一些函数式和OO风格。我觉得有点奇怪,您使用异常作为唯一的可选值。通常,客户应该是包含可选性的价值,匹配应该是客户是否有价值 在类型系统中处理错误的典型方法是使用
或类型
type Either<'a,'b> =
| Left of 'a
| Right of 'b
关于错误代码的部分听起来非常错误,我想知道你在哪里找到的 您可能想阅读Scott Wlaschin的优秀文章,了解如何用F#函数化地建模错误。如果没有这篇文章的介绍,很难反驳其论点。IMO异常不同于任何类型的返回值(无论是包装在选项中还是有区别的联合类型中),允许故障点和处理点之间的中间代码更干净。在实际应用中,这种中间代码占大多数。理查德:这是真的,但是一个以异常终止的函数会产生副作用,如果你想用纯函数的方式编写F#,你就不希望这样。
// 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