cyr*_*huk 5 f# functional-programming function
问题是:
何时使用私有函数,何时使用嵌套函数?(我问的是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
Run Code Online (Sandbox Code Playgroud)
嵌套函数可以使用来自更高范围的数据,这是一个很大的好处。也不会污染周围的模块。但看起来很笨拙,不是吗?特别是当有一些大的嵌套函数时
相反,私有函数可以公开并进行测试。似乎它们看起来更具可读性
你怎么看?
我经常在模块中使用private
函数——通常用于由模块中的其他函数使用的“辅助”函数,但不需要暴露给外部代码。
函数的另一个用例private
是简单地使代码更具可读性。如果一个函数嵌套在另一个函数中,但它太长而难以阅读——例如,如果嵌套函数的代码占了它所包含的函数长度的一半以上——我通常会将其移出到模块级别并使其private
调用者函数的代码更容易理解。
嵌套函数可以使用更高范围的数据,这是一个很大的好处。也不会污染周围的模块。
我同意你的观点。我的建议是将函数保持在正确的范围内。例如,如果函数仅在一个地方使用,那么最好是嵌套函数。例如,没有必要loop
向上移动并使其成为一个private
函数。
let length xs =
let rec loop acc = function
| [] -> acc
| _::xs -> loop (acc + 1) xs
loop 0 acc
Run Code Online (Sandbox Code Playgroud)
但看起来很笨拙,不是吗?特别是当有一些大型嵌套函数时
如果您需要大型嵌套函数,那么您可能做错了。它们应该被分成多个小的嵌套函数,或者最外面的函数应该转换为类型。
相反,私有函数可以公开并进行测试。而且看起来它们看起来更具可读性。
可读性是一个主观问题。我认为组织问题更重要。嵌套函数的优点是它们很简单,并且可以通过测试最外面的函数来测试。
当函数具有更多适用性时,您可以将它们放入实用程序模块中,并在需要时打开该模块。请注意,除了标记函数之外,还有其他隐藏函数的技术private
。例如,您可以使用fsi
文件来指示公开的接口。