F#实例方法......它们应该返回一个新实例而不是改变当前对象吗?

时间:2011-10-31 17:02:29

标签: f# immutability

问题是实例方法是否应该改变包含该方法的对象,还是应该返回一个新实例?我是F#的新手,也是为F#建议的完全可用性的概念。

现在只使用伪代码,除非我需要更具体。

首先想到的是将消息添加到对象的消息列表中:

class Something
  ctr(messages)
     _messages.Add(messages)

  AddMessage(message)
   _messages.Add(message)

其次是构建一个连接旧列表和新消息的新列表。然后我会创建一个新的实例altogther并发回。

class Something
  ctr(messages)
     _messages.Add(messages)

  AddMessage(message)
    newMessageList = _messages.Join(message)
      return new Something(newMessageList)

我是否在追求不变性?

2 个答案:

答案 0 :(得分:4)

在我看来,答案取决于您的要求。不可变的风格可能更惯用,并且是一个明智的默认。然而,关于F#的一个好处是你可以根据你的需要选择做什么;使用变异的代码没有任何内在错误。以下是一些需要考虑的事项:

  • 有时候,可变方法会带来更好的性能,特别是在单线程环境中使用时(但要确保测量真实场景!)
  • 有时,不可变方法更适合在多线程场景中使用
  • 有时您希望与使用不透明代码更容易使用的库(例如,采用System.Action<_>的API)进行交互。
  • 你在团队工作吗?如果是这样,他们是否经历过C#开发人员?经验丰富的F#开发人员?他们会发现什么样的代码最容易阅读(也许是可变的样式)?你会发现哪种代码最容易维护(可能是不可变的样式)?
  • 你刚刚做这个运动吗?然后练习不变的风格可能是值得的。

进一步退缩,还有一些其他要点需要考虑:

  • 你真的需要一个实例方法吗?通常,在模块中使用let-bound函数更具惯用性。
  • 你真的需要一个新的名义类型来做你正在做的事情吗?如果它只是列表中的一个薄包装器,您可以考虑直接使用list

答案 1 :(得分:1)

当你正在进行“基于类”的编程时,这是进行面向对象编程的一种方式(相当不幸),你将进行状态修改而不是返回一个新的状态(因为这是预期的结果)你在做OO)。

如果你真的想要进入不变性,那么我建议你需要使用更多的FP概念,比如模块,函数(不是基于类编程的方法),递归数据类型等。

我的答案过于笼统,恰当的答案在于,您的这一类将如何适应您的应用程序设计的大局。