隔离对象状态的共享?

时间:2018-10-01 15:13:13

标签: f#

我的代码使用以下共享库

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模块。可能有以下几种方法

  1. 向所有调用共享库的函数添加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 ....
    
  2. 定义一个可变变量,并在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#?代码应如何构建?

1 个答案:

答案 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函数使用其他函数执行特定的,更复杂的操作,通过使用管道前移运算符将当前状态通过每个函数进行线程化。