私有函数vs嵌套函数
问题是:私有函数vs嵌套函数
何时使用私有函数以及何时使用嵌套函数? (我问F#但也许答案可以在其他功能的语言有关)
一个小例子
namespace SomeName
module BinaryReaderExt =
open System.IO
let seek (reader : BinaryReader) positions =
reader.BaseStream.Seek(positions, SeekOrigin.Current) |> ignore
module Mod =
open System.IO
let private prFun reader:BinaryReader =
//do something
BinaryReaderExt.seek reader 10L
let outerFun (stream :System.IO.Stream) =
let reader = new System.IO.BinaryReader(stream)
let seek = BinaryReaderExt.seek reader
let nestedFun() =
seek 10L
//do something
nestedFun()
prFun reader
这是一个巨大的奖赏,即在嵌套函数可以从更高的范围内使用的数据。也不污染周围的模块。但看起来很笨拙,不是吗?特别是当有一些大的嵌套功能
相反,私人功能可以公开并被测试。看起来它们看起来更具可读性
你的意见是什么?
嵌套函数可以使用更高范围的数据是一个很大的好处。也不污染周围的模块。
我同意你的观点。 我的建议是保持功能在正确的范围。例如,如果函数仅用于一个地方,最好是嵌套函数。例如,将loop
向上移动并使其成为private
函数没有意义。
let length xs =
let rec loop acc = function
| [] -> acc
| _::xs -> loop (acc + 1) xs
loop 0 acc
但就是看似笨拙,不是吗?特别是当有一些大的嵌套功能
如果你需要大的嵌套函数,那很可能你做错了。它们应该被分解成多个小嵌套函数,或者最外面的函数应该被转换为一个类型。
相反,私人功能可以公开并进行测试。看起来他们看起来更具可读性。
可读性是一个主观的问题。我认为组织问题更重要。嵌套函数的要点是它们很简单,可以通过测试最外层函数来测试。
当函数具有更多适用性时,可以将它们放入实用程序模块并在需要时打开该模块。请注意,除标记功能外,还有其他技术可以隐藏功能private
。例如,您可以使用fsi
文件来指示公开的接口。
不幸的是,有些情况下你不能将函数分解成小的函数,因为那些小函数没有意义。另外我还必须补充一点,问题是关于只有作为另一个函数的一部分才有意义的函数(在我的例子中,outerFun),并不意味着它可以被模块中的其他函数重用。也许'私人'在这里是不对的。谢谢你的好回答! – 2013-04-07 12:33:45
我在模块中经常使用private
函数 - 通常用于模块中其他函数使用但不需要暴露给外部代码的“帮助”函数。
private
函数的另一个用例是简单地使代码更具可读性。如果一个函数嵌套在另一个函数中,但是它的读取时间太长 - 例如,如果嵌套函数的代码占函数长度的一半以上 - 我通常会将它移动到模块级别并使其成为private
,因此调用者函数的代码更易于理解。
在真正的代码中看到'let private'非常少见 - 我认为使用私有方法创建类型会比较普遍 – 2013-04-07 06:41:24
我同意'let private'不是很常见,但我认为可能仅仅是因为F#的传统功能。我其实很喜欢'让私人',并发现它非常有用(当私人功能是一个独立的功能)。 – 2013-04-07 13:26:57
私人模块功能的一个刺激...当试图在F#Interactive中运行它们时...我得到这个“错误FS1094:'myPrivateFunction'的值无法从此代码位置访问。我必须删除'private',将函数添加到F#Interactive中,并记得在完成时替换'private'。 – Wally 2015-03-26 18:04:13