为什么F#编译器会因此中缀运算符而失败?

时间:2013-07-04 17:26:17

标签: f#

我有一个类和一个如此定义的记录:

namespace Foo
    type internal MyRecord = 
        {
            aValue1 : int
            aValue2 : int
        }
        static member (+) (left : MyRecord, right : MyRecord) : MyRecord =
            {aValue1 = left.aValue1 + right.aValue1; aValue2 = left.aValue2 + right.aValue2;}

    type internal Bar() =
        member this.Baz() = 
            let myRecord1 = {aValue1 = 2; aValue2 = 3;}
            let myRecord2 = {aValue1 = 7; aValue2 = 5;}
            let sum = myRecord1 + myRecord2 //Does not compile
            0

无法编译:

  

成员或对象构造函数“op_Addition”不公开。只能在声明类型中访问私有成员。受保护的成员只能从扩展类型访问,不能从内部lambda表达式访问。

两种类型都是内部的。如果我明确地将+运算符设置为public,则无效:

static member public (+) (left : MyRecord, right : MyRecord) : MyRecord

的工作原理只是放弃使用运算符并使用静态方法:

namespace Foo
    type internal MyRecord = 
        {
            aValue1 : int
            aValue2 : int
        }
        static member Add (left : MyRecord, right : MyRecord) : MyRecord =
            {aValue1 = left.aValue1 + right.aValue1; aValue2 = left.aValue2 + right.aValue2;}

    type internal Bar() =
        member this.Baz() = 
            let myRecord1 = {aValue1 = 2; aValue2 = 3;}
            let myRecord2 = {aValue1 = 7; aValue2 = 5;}
            let sum = MyRecord.Add(myRecord1, myRecord2) //Does compile
            0

为什么在使用命名成员工作时,F#编译器在使用运算符时会遇到什么困难?

将两种类型更改为公共而不是内部也可以解决编译错误。

我正在使用Visual Studio 2012和F#3.0,目标是.NET Framework 3.5。

1 个答案:

答案 0 :(得分:6)

我不知道为什么F#编译器有这个问题。这可能与F#中操作符的处理方式有关,也可能与处理可访问性的方式有关。你必须记住,用这种语言并不是一切都是它看起来的样子。通过做出一些牺牲已经实现了一些“面向对象”的特征。也许这就是其中之一。

但是。我知道如何解决这个:)。不要在实现文件中将类型设置为内部。而是使用签名。像这样定义文件Foo.fsi:

namespace Foo
    type internal MyRecord = 
        {
            aValue1 : int
            aValue2 : int
        }

    [<Class>]
    type Bar =
        member Baz : unit -> int
像这样的

和Foo.fs:

namespace Foo
    type MyRecord = 
        {
            aValue1 : int
            aValue2 : int
        }
        static member (+) (left : MyRecord, right : MyRecord) : MyRecord =
            {aValue1 = left.aValue1 + right.aValue1; aValue2 = left.aValue2 + right.aValue2;}

    type Bar() =
        member this.Baz() = 
            let myRecord1 = {aValue1 = 2; aValue2 = 3;}
            let myRecord2 = {aValue1 = 7; aValue2 = 5;}
            let sum = myRecord1 + myRecord2 //Compiles
            0

这使您的代码有效,MyRecord内部。