为什么F#编译器使用此infix运算符失败?
我有一个类和一条记录,定义如下:
I have a class and a record defined like so:
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
无法通过以下方式进行编译:
This fails to compile with:
成员或对象构造函数"op_Addition"不是公共的.私有成员只能在声明类型内访问.受保护的成员只能从扩展类型访问,而不能从内部Lambda表达式访问.
The member or object constructor 'op_Addition' is not public. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions.
这两种类型都是内部的.如果我将+
运算符显式设置为public,那也无济于事:
Both types are internal. If I explicitly set the +
operator to public, that doesn't help either:
static member public (+) (left : MyRecord, right : MyRecord) : MyRecord
所做的工作只是放弃使用运算符并使用静态方法:
What does work is just forgoing use of an operator and using a static method:
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#编译器在使用运算符时会遇到麻烦?
Why does the F# compiler struggle with using an operator in this case when using a named member work just fine?
将这两种类型都改为公开而不是内部也可以解决编译错误.
Changing both types to be public instead of internal resolves the compilation error, too.
我正在使用Visual Studio 2012和F#3.0,目标是.NET Framework 3.5.
I'm using Visual Studio 2012 with F# 3.0 targeting .NET Framework 3.5.
我不知道为什么F#编译器有此问题.这可能与F#中操作符的处理方式或可访问性的处理方式有关.您必须记住,用这种语言显示的并不是一切.通过做出一些牺牲,已经实现了一些面向对象"的功能.也许这是其中之一.
I do not know why F# compiler has this problem. This is probably connected to the way operators are handled in F# or maybe how accessibility is handled. You must remember that in this language not everything is what it seems. Some "object oriented" features have been achieved by making some sacrifices. Maybe this is one of them.
但是.我知道如何解决这个问题:).不要在实现文件中将您的类型设置为内部.而是使用签名.像这样定义文件Foo.fsi:
But. I know how to resolve this :). Do not make your types internal in implementation file. Instead use Signatures. Define file Foo.fsi like this:
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
.
This makes your code valid and MyRecord
internal.