不是F#记录为什么允许有AllowNullLiteralAttribute? [英] Why aren't F# records allowed to have AllowNullLiteralAttribute?

查看:143
本文介绍了不是F#记录为什么允许有AllowNullLiteralAttribute?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我看到这种约束力量清洁code,但有时并非总是如此。

  [< AllowNullLiteralAttribute>]
键入IBTreeNode = {
    可变左:IBTreeNode;可变权:IBTreeNode;可变的值:INT}

    成员this.Insert X =
        如果x< THIS.VALUE然后
            如果this.left = null,则
                this.left&下 - {左=无效;右= NULL;值= X}
            其他
                this.left.Insert点¯x
        其他
            如果this.right = null,则
                this.right&下 - {左=无效;右= NULL;值= X}
            其他
                this.right.Insert点¯x//将是一个很大的样板,如果我想这些公共
并[d AllowNullLiteralAttribute]的计算值
键入CBTreeNode(值)=
    让左可变= NULL
    让可变权= NULL
    让可变值=价值

    成员this.Insert X =
        如果x<值,则
            如果离开= null,则
                左< - CBTreeNode(X)
            其他
                left.Insert点¯x
        其他
            如果右= null,则
                右LT; - CBTreeNode(X)
            其他
                right.Insert点¯x

增加了一个不可改变的版本上的可变性人群皱眉。这是在这种情况下快30%左右。

 键入奥布特雷埃=
    |奥布特雷埃的节点*奥布特雷埃* INT
    |空值

    成员this.Insert X =
        符合这个用
        |节点(左,右,值)当X =价值 - >节点(left.Insert X,右,值)
        |节点(左,右,值) - GT;节点(左,right.Insert X,值)
        |空 - >节点(NULL,NULL,X)


解决方案

我只能大胆地猜测,但语言似乎采取的立场是,使用的是可避免的东西(你可以随时使用选项如果你需要的功能型),所以使用真的东西,应该被限制在互操作与其他.NET语言。因此,F#的特定类型不允许使用

Is there a compiler implementation reason why records can't have the AllowNullLiteralAttribute attribute or is this a chosen constraint?

I do see this constraint force cleaner code sometimes but not always.

[<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

Added an immutable version for the frown on mutability crowd. It's about 30% faster in this case.

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)

解决方案

I can only hazard a guess, but the language seems to take the position that the use of null is something to be avoided (you can always use an option type if you need that functionality), and so the use of null is really something that ought to be limited to interop with other .NET languages. Therefore, F# specific types don't allow the use of null.

这篇关于不是F#记录为什么允许有AllowNullLiteralAttribute?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆