Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 如何使用公共字段声明不可变结构?_F# - Fatal编程技术网

F# 如何使用公共字段声明不可变结构?

F# 如何使用公共字段声明不可变结构?,f#,F#,我想用F来写这个C的等价物: 这将强制用户提供参数来创建实例[编辑:这对于值类型是错误的-所有值类型都有默认构造函数]。默认Vector2还可以提供一个静态只读字段,即Vector2.Zero 看起来获取公共字段的唯一方法是通过“val”关键字,但似乎不允许我使用默认构造函数初始化它们,而且我不希望有两个构造函数: [<Struct>] type MyInt(value) = val public Value : int = value;;

我想用F来写这个C的等价物:

这将强制用户提供参数来创建实例[编辑:这对于值类型是错误的-所有值类型都有默认构造函数]。默认Vector2还可以提供一个静态只读字段,即Vector2.Zero

看起来获取公共字段的唯一方法是通过“val”关键字,但似乎不允许我使用默认构造函数初始化它们,而且我不希望有两个构造函数:

  [<Struct>]
  type MyInt(value) =
        val public Value : int = value;;

          val public Value : int = value;;
  -------------------------------^

stdin(7,32): error FS0010: Unexpected symbol '=' in member definition
[]
类型MyInt(值)=
val公共值:int=Value;;
val公共值:int=Value;;
-------------------------------^
stdin(7,32):错误FS0010:成员定义中出现意外符号“=”
我知道这可以通过成员绑定来实现,但如果我理解得很好,这会创建属性,而不是字段。

根据这一点,这可以通过

type Vector2 =
   struct 
      val public X: int
      val public Y: int
      new(x: int, y: int) = { X = x; Y = y }
   end
如果F#对你有效,那么这将有效:

type MyInt = {
    Value: int
};;
然后初始化:

let i = {Value=1};;
因为我不完全确定您的用例,所以我不确定这有多大帮助

编辑: 值得一提的是,如果您选择值类型的原因是希望值类型相等语义,则记录支持该语义(即使它们是引用类型)。考虑这一点:

type Vector2 = {
     X:int;
     Y:int
};;

type Vector2 =
  {X: int;
   Y: int;}

let v = {X=1;Y=1};;

val v : Vector2 = {X = 1;
                   Y = 1;}

let v2 = {X=1;Y=1};;

val v2 : Vector2 = {X = 1;
                    Y = 1;}

v = v2;;
val it : bool = true

let v3 = {X=2;Y=2};;
v = v3;;
val it: bool = false

我的意思是,尽管记录是引用类型,但人们使用值类型(相等语义)的原因之一并不是记录的问题。尽管它是一种引用类型,但我相信它更接近于您试图模拟的C代码的行为——不管它值多少。

不幸的是,这让我可以在不传递参数的情况下创建一个向量,比如:
让v=Vector2()
。这并不是一个非常严重的问题,但我仍然想知道是否可以在没有默认空构造函数的情况下完成它。@Asik:您的C代码也是如此——这是CLR限制,而不是F限制。“结构不能有没有参数的对象构造函数。这是对所有CLI语言的限制,因为结构自动支持默认构造函数。“-这是编译器所说的,所以你不能总是得到你想要的…啊,我问题的前提是错误的。对于引用类型,不会生成默认构造函数,因此F#和C#在这方面确实是等价的。酷,问题回答了。记录的问题是,它们被实现为带有属性的引用类型,而我在这里尝试获取带有字段的值类型。同样,我不知道您的用例,但即使记录是引用类型,它们也具有值类型相等语义。我已经编辑了我的答案来进一步解释它。我没有一个真正的用例,我只是试图理解如何使用公共不可变字段(在CLR意义上)创建一个值类型,并避免使用默认构造函数。谢谢你的解释。
type Vector2 = {
     X:int;
     Y:int
};;

type Vector2 =
  {X: int;
   Y: int;}

let v = {X=1;Y=1};;

val v : Vector2 = {X = 1;
                   Y = 1;}

let v2 = {X=1;Y=1};;

val v2 : Vector2 = {X = 1;
                    Y = 1;}

v = v2;;
val it : bool = true

let v3 = {X=2;Y=2};;
v = v3;;
val it: bool = false