代码之家  ›  专栏  ›  技术社区  ›  gradbot

为什么不允许F#记录具有AllowNullLiteralAttribute?

  •  3
  • gradbot  · 技术社区  · 15 年前

    记录不能具有allownullliteraltribute属性是否有编译器实现的原因,或者这是一个选定的约束?

    我确实有时会看到这种约束强制清理代码,但并不总是这样。

    [<AllowNullLiteralAttribute>]
    type IBTreeNode = {
        mutable left : IBTreeNode; mutable right : IBTreeNode; mutable value : int}
    with
        member this.Insert x =
            if x < this.value then
                if this.left = null then
                    this.left <- {left = null; right = null; value = x}
                else
                    this.left.Insert x
            else
                if this.right = null then
                    this.right <- {left = null; right = null; value = x}
                else
                    this.right.Insert x
    
    // Would be a lot of boilerplate if I wanted these public
    [<AllowNullLiteralAttribute>]
    type CBTreeNode(value) = 
        let mutable left = null
        let mutable right = null
        let mutable value = value
    with
        member this.Insert x =
            if x < value then
                if left = null then
                    left <- CBTreeNode(x)
                else
                    left.Insert x
            else
                if right = null then
                    right <- CBTreeNode(x)
                else
                    right.Insert x
    

    添加了一个不可变的版本对不赞成可变人群。在这种情况下大约快30%。

    type OBTree =
        | Node of OBTree * OBTree * int
        | Null
    with
        member this.Insert x =
            match this with
            | Node(left, right, value) when x <= value -> Node(left.Insert x, right, value)
            | Node(left, right, value) -> Node(left, right.Insert x, value)
            | Null -> Node(Null, Null, x)
    
    2 回复  |  直到 15 年前
        1
  •  3
  •   kvb    15 年前

    null 是需要避免的事情(你可以用 option 无效的 实际上,它应该仅限于与其他.NET语言的互操作。因此,F#特定类型不允许使用 无效的 .

        2
  •  2
  •   Dario    15 年前

    我想这个决定很有哲理- Null

    因此,我认为记录类型作为一种“功能性构造”(与标准.NET不兼容)并不意味着要携带这样的非功能性数据,而是要求用户手动编码(“选项类型”等)。

    这还允许您对代码进行推理,例如检查所有可能值的模式匹配,而不必处理潜在的危险 null 价值观。

    data Tree = 
        | Node of int * Tree * Tree
        | Nil