D Nullable inout构造函数创建可变对象

D Nullable inout构造函数创建可变对象,d,D,以下代码在尝试编译时给了我一个奇怪的错误: import std.conv: to; import std.typecons; import std.traits; void main() { alias BuiltinScalars = TypeTuple!(ubyte, byte, ushort, short, uint, int, ulong, long, float, double, real, ch

以下代码在尝试编译时给了我一个奇怪的错误:

import std.conv: to;
import std.typecons;
import std.traits;

void main()
{
    alias BuiltinScalars = TypeTuple!(ubyte, byte, ushort, short, uint, int, ulong, long, 
                                      float, double, real, char, wchar, dchar, bool,
                                      ifloat, idouble, ireal, cfloat, cdouble, creal);

    foreach (T; BuiltinScalars)
    {
        foreach (ValT; BuiltinScalars)
        {
            alias KeyT = T;
            alias AAT = ValT[KeyT];
            foreach (NullableAAT; TypeTuple!(Nullable!AAT, const(Nullable!AAT), immutable(Nullable!AAT)))
            {
                NullableAAT naa;
                assert(naa.to!string() == "Nullable.null");

                static if (!isSomeString!KeyT)
                    enum KeyTInit = KeyT.init;
                else
                    enum KeyTInit = `""`;

                NullableAAT naav = [KeyTInit:ValT.init];
                assert(naav.to!string() == '[' ~ KeyTInit.to!string() ~ ':' ~ ValT.init.to!string() ~ ']');
            }
        }        
    }
}
我不知道这个代码有什么问题。Nullable只有一个构造函数,其签名为
this(inout T value)inout

奇怪的是(或者可能并不奇怪。可能是编译器在出现了这么多错误后才放弃)并非所有类型的组合都会出现错误,只有那些将ubyte作为键类型的组合才会出现错误。完整的错误输出为:

bug.d(46): Error: inout constructor std.typecons.Nullable!(ubyte[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(byte[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(ushort[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(short[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(uint[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(int[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(ulong[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(long[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(float[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(double[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(real[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(char[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(wchar[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(dchar[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(bool[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(ifloat[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(idouble[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(ireal[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(cfloat[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(cdouble[ubyte]).Nullable.this creates mutable object, not immutable
bug.d(46): Error: inout constructor std.typecons.Nullable!(creal[ubyte]).Nullable.this creates mutable object, not immutable

默认情况下,关联数组文字是可变的

若要修复,您可以替换:

            NullableAAT naav = [KeyTInit:ValT.init];
与:

这将声明具有正确常数的AA,该常数将通过构造函数的
inout
传播到
Nullable

奇怪的是(或者可能并不奇怪。可能是编译器在出现了这么多错误后才放弃)并非所有类型的组合都会出现错误,只有那些将ubyte作为键类型的组合才会出现错误


是的,它在第二个循环的第一次迭代后停止。您可以通过从元组的头部删除类型来进行测试。

那么,我想AAs还不能从唯一性推断中获益吗?或者是由于其他原因,无法将文本推断为常量、不可变等?AAs并没有什么特别之处—您的代码希望常量从变量声明一直传播到可为null的inout构造函数,再传播到AA。实际上,传播的方向不同:构造函数参数的常量定义了构造对象的常量。
            alias CAA = typeof(naa.get());
            CAA aa = [KeyTInit:ValT.init];
            NullableAAT naav = aa;