对于 F# 中的递归,现有文档清楚地说明了在只有一个函数调用自身或一组物理上相邻的函数相互调用的特殊情况下如何执行递归。
但一般情况下,不同模块中的一组函数需要相互调用,该怎么做呢?
我认为在 F# 中没有办法实现这一点。通常可以以不需要这样做的方式构建应用程序,因此如果您描述了您的场景,您可能会得到一些有用的注释。
无论如何,有多种方法可以解决该问题 - 您可以声明一条记录或一个接口来保存需要从模块导出的函数。接口也允许您导出多态函数,因此它们可能是更好的选择:
// Before the declaration of modules
type Module1Funcs =
abstract Foo : int -> int
type Module2Funcs =
abstract Bar : int -> int
然后,模块可以导出一个实现接口和函数之一的值,要求另一个模块可以将其作为参数(或者您可以将其存储在可变值中)。
module Module1 =
// Import functions from Module2 (needs to be initialized before using!)
let mutable module2 = Unchecked.defaultof<Module2Funcs>
// Sample function that references Module2
let foo a = module2.Bar(a)
// Export functions of the module
let impl =
{ new Module1Funcs with
member x.Foo(a) = foo a }
// Somewhere in the main function
Module1.module2 <- Module2.impl
Module2.module1 <- Module1.impl
初始化也可以使用反射自动完成,但这有点难看,但是如果你really经常需要它,我可以想象为此开发一些可重用的库。
在许多情况下,这感觉有点难看,重组应用程序以避免递归引用是更好的方法(事实上,我发现面向对象编程中的类之间的递归引用通常非常令人困惑)。但是,如果您确实需要这样的东西,那么使用接口/记录导出函数可能是唯一的选择。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)