我的代码使用以下共享库
Module Shared
let state = new AClrClass()
let fun1 x .... = // shared function
.... // uses state
使用共享库的示例,state
被所有函数共享,即使同时调用多个main
函数(在以下代码中)。
Module Caller
let f1 x = Shared.fun1 x .... // other code omitted
let f2 x = Shared.fun1 x .... // many other functions uses the function in the Shared lib
let main () = // entry point of the module. Calls f1, f2, f3...
现在,我将需要切换到Shared
的不同实现,该实现定义了一个类(因此,每次对Caller.main
的调用都将拥有自己的state
)
Module Shared
type Shared () =
let state = new AClrClass()
member __.Fun1 x .... = // shared function
.... // uses state
我将需要更新Caller
模块。可能有以下几种方法
向所有调用共享库的函数添加aClrObj
的另一个参数
Module Caller
let f1 o x .... = o.Fun1 x .... // other code omitted
let f2 o x .... = o.Fun1 x .... // many other functions uses the function in the Shared lib
let main () = // entry point of the module. Calls f1, f2, f3...
let aClrObj = new AClrClass()
f1 aClrOjb x ....
定义一个可变变量,并在main
函数中进行设置。
Module Caller
let mutable o = new AClrClass()
let f1 x .... = o.Fun1 x .... // other code omitted
let f2 x .... = o.Fun1 x .... // many other functions uses the function in the Shared lib
let main () = // entry point of the module. Calls f1, f2, f3...
o <- new AClrClass()
let aClrObj = new AClrClass()
f1 aClrOjb x ....
哪种方法更适合F#?代码应如何构建?
答案 0 :(得分:5)
从我的评论中扩展
从代码示例中并不清楚模块应该做什么。但是,通常,可以通过使每个函数将状态作为其最后一个参数并返回新状态作为其值来通过函数传递状态。然后,您的main
函数(或任何公开公开的函数)可以初始化状态,并通过调用它执行工作的任何函数来传递状态,返回最终状态。
这是一个简单的例子:
type State = State of int
let add x (State state) =
State (state + x)
let subtract x (State state) =
State (state - x)
let multiply x (State state) =
State (state * x)
let divide x (State state) =
State (state / x)
let main () =
State 0
|> add 3
|> multiply 4
|> subtract 2
|> divide 5
// returns (State 2)
这使用State
对象通过每个函数来线程化当前执行状态。每个函数都采用当前状态并对其执行操作,并返回新状态。 main
函数使用其他函数执行特定的,更复杂的操作,通过使用管道前移运算符将当前状态通过每个函数进行线程化。