我正在研究基本的2D CAD引擎,管道运算符显着改进了我的代码.基本上,几个函数以空间中的点(x,y)开始,并在多次移动操作后计算最终位置:
let finalPosition =
startingPosition
|> moveByLengthAndAngle x1 a1
|> moveByXandY x2 y2
|> moveByXandAngle x3 a3
|> moveByLengthAndAngle x4 a4
// etc...
Run Code Online (Sandbox Code Playgroud)
这非常容易阅读,我想保持这种方式.各种x1,a1等在实际代码中显然具有含义名称.
现在新的要求是引入异常处理.围绕整个操作链进行一次大尝试是不够的,因为我想知道哪一行引起了异常.我需要知道哪个参数无效,以便用户知道必须更改哪个参数.
例如,如果第一行(moveByLengthAndAngle x1 a1)引发异常,我想告诉类似"嘿,-90是a1的无效值!a1必须在45到90之间!".鉴于可以在序列中使用相同类型的许多操作,仅为每个操作定义不同的异常类型是不够的(在该示例中,我将无法判断错误是第一次还是最后一次移动).
显而易见的解决方案是在单个let语句中拆分链,每个语句在各自的try/with中.然而,这将使我漂亮和可读的代码有点凌乱,不再那么可读.
有没有办法满足这个要求,而不会牺牲当前代码的可读性和优雅性?
(注意.现在每个moveBy函数都会在出现错误的情况下引发异常,但我可以自由地更改ex.返回一个选项,一个更大的元组,或者只需要其他任何东西).
f# ×1