面向混合功能/面向对象的语言,如F#/ Scala:使用带有方法或方法和类型的类型

时间:2012-01-11 19:48:26

标签: oop scala f# functional-programming

所以,为了补充我从这个问题中学到的东西,我问:

F# Records: Dangerous, only for limited use, or well used functionality?

这让我想到我是否应该使用带方法或记录(?)和方法的类型。例如,这是我可能做出的典型类型:

(* User Interaction Start *)

type UserInteraction public() = 

  member public x.CreatePassword(originalPassword) =
    if String.IsNullOrEmpty originalPassword then
      raise(new ArgumentException "CreatePassword: password is null or empty")
    let hashUtility = new HashUtility();

    hashUtility.CreateHash originalPassword

我可以看到的问题是,由于允许,UserInteraction类型中的某些内容可能是可变的。现在有记录类型,据我所知,它们保证是不可变的。

使用仅接收或返回记录类型的方法设计一个模块会更好吗,或者甚至更进一步使用方法链接?

2 个答案:

答案 0 :(得分:8)

您可能需要阅读When to Use Classes, Unions, Records, and Structures [MSDN](页面底部)。您似乎对记录有一些不正确的假设。例如,他们可以像类一样拥有可变字段。重要的区别是继承,模式匹配,构造函数,隐藏成员,相等以及复制和更新表达式。

刚刚注意到该页面上的一个小错误:记录实际上可以实现接口。

另一个可能有帮助的部分:Differences Between Records and Classes [MSDN](页面底部)

答案 1 :(得分:3)

请注意,您可以在不可变类型上创建一个成员,返回该类型的新修改实例,这是完全合理的事情:

type Person =
    { Name : string; Age : int }

    member x.GrowOlder n =
        { x with Age = x.Age + n }

let q = { Name = "David"; Age = 29 };;
q.GrowOlder 1

值得注意的是,在以下C#代码中:

var x = 0;
var y = 1;
var z = x + y;

你不会指望x和y都不会被运算符+变异,即+返回一个新值并且不会改变x或y。您通常可以考虑设计所有内容。