我有一个关于在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
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
现在在我看来,我认为例子1更清晰,更多的是F#的观点和风格。由于在函数式编程中处理语句并不是“自然”,因此我们将语句显式地包装在do块中以表明它们是副作用。但我想知道,关于这个的惯例是什么?
答案 0 :(得分: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
另一个必须使用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))