F#在do块中包装语句

Ove*_*ive 3 f# functional-programming conventions statements

我有一个关于在F#中使用do块的约定的问题.在使用.NET库类和其他.NET代码时,首先会出现这种情况.

让我给你举个例子.

1.使用do块包含语句:

let drawHelloName (width:int, height:int) name = 
    let bmp = new Bitmap(width, height)
    use fnt = new Font("Arial", 12.0f)
    use gr = Graphics.FromImage(bmp)
    do
        gr.Clear(Color.White)
        gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
    bmp
Run Code Online (Sandbox Code Playgroud)

2.没有阻止:

let drawHelloName (width:int, height:int) name = 
    let bmp = new Bitmap(width, height)
    use fnt = new Font("Arial", 12.0f)
    use gr = Graphics.FromImage(bmp)
    gr.Clear(Color.White)
    gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
    bmp
Run Code Online (Sandbox Code Playgroud)

现在在我看来,我认为例子1更清晰,更符合F#的观点和风格.由于在函数式编程中处理语句并不是"自然",因此我们将语句显式地包装在do块中以表明它们是副作用.但我想知道,关于这个的惯例是什么?

pad*_*pad 7

由于在函数式编程中处理语句并不是"自然",因此我们将语句显式地包装在do块中以表明它们是副作用.

我同意你的看法.但是,如果你在野外研究F#代码,那么它们往往会松散.没有严格的约定,只要按照您认为最适合您的方式.

另一点是do块为我们想要明确控制其生命周期的值创建新的范围.例如,如果您想先处理gr并继续使用fnt,可以将您的第一个函数写入:

let drawHelloName (width:int, height:int) name = 
    let bmp = new Bitmap(width, height)
    use fnt = new Font("Arial", 12.0f)
    do
        use gr = Graphics.FromImage(bmp)
        gr.Clear(Color.White)
        gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
    (* Continue to do something with 'fnt' *)
    bmp
Run Code Online (Sandbox Code Playgroud)

你必须使用do块的另一个地方是隐式构造函数,例如

type T(width, height) =
    let bmp = new Bitmap(width, height)
    use fnt = new Font("Arial", 12.0f)
    use gr = Graphics.FromImage(bmp)
    do
        gr.Clear(Color.White)
        gr.DrawString(name, fnt, Brushes.Black, PointF(10.0f, 10.0f))
Run Code Online (Sandbox Code Playgroud)