class - 引用 'this'的F#结构成员导致错误

标签 class struct f# this seq

新的F#开发人员,长期的C#开发人员。作为学习F#的练习,我正在研究Eric Lippert关于图形着色的系列,从他的C#转换为F#。我目前正在研究part two

原始的C#在博客文章中-到目前为止,这是F#的翻译-但无法编译:

type BitSet = struct
        val bits : int
        private new(b) = { bits = b }

        static member Empty = BitSet(0)

        member this.Contains (item:int) = (this.bits &&& (1<<< item)) <> 0
        member this.Add (item:int) = BitSet(this.bits ||| (1 <<< item))
        member this.Remove (item:int) = BitSet(this.bits &&& ~~~(1<<<item))
        member this.Bits = seq {
                for item in 0..31 do
                    if this.Contains(item) then
                        yield item
            }
    end

这会产生非常神秘的错误“错误FS0406:Byref类型的变量'this'以无效方式使用。Byref无法被闭包捕获或传递给内部函数”,该定义来自Bits:seq 的定义。

奇怪的是,将关键字“struct”更改为“class”会得到有效的代码。从C#的角度来看,这似乎是胡说八道,但是我敢肯定背后有一个正当的理由。问题是-我应该如何编写Bits函数?为了使之有意义,我需要了解什么基本的F#原理?

最佳答案

我认为问题在于,创建了this引用作为对该结构体当前值的引用,以便您可以修改该结构体(如果需要并且该结构体是可变的)。

这会导致seq { .. }内部出现问题,因为这会在另一个类中生成代码,因此编译器无法将引用传递给“this”实例。

如果为this值分配一个普通的局部变量,则该代码可以正常工作:

member this.Bits = 
    let self = this
    seq {
        for item in 0..31 do
            if self.Contains(item) then
                yield item
     }

作为样式问题-我可能会使用隐式构造函数,这会使代码短一些。与显式的Struct语法相比,我也更喜欢struct .. end属性,但是这两者都只是样式问题(我敢肯定其他人会有不同的偏好)。您可能会发现它作为替代或比较有用:
[<Struct>]
type BitSet private (bits:int) = 
    static member Empty = BitSet(0)
    member this.Contains (item:int) = (bits &&& (1<<< item)) <> 0
    member this.Add (item:int) = BitSet(bits ||| (1 <<< item))
    member this.Remove (item:int) = BitSet(bits &&& ~~~(1<<<item))
    member this.Bits = 
        let self = this
        seq {
            for item in 0..31 do
                if self.Contains(item) then
                    yield item
        }

关于class - 引用 'this'的F#结构成员导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41452698/

相关文章:

c - 有多大的结构可以有效地按值传递?

c - 部分复制 C 中的结构体

f# - 递归 let 绑定(bind)的非轻型语法是什么?

f# - Stackless trampoline Monad/计算表达式

swift - 类不符合 NSObjectProtocol

java - 一个类可以在哪三种不同的上下文中声明?

c - int数组到C中的struct数组

model-view-controller - 如何分别观察一个界面的不同概念?

java - 查找引用的 jar 的主类

java - 不同方法中的变量放在一起