检查可选参数的测试函数

Test function for checking an optional argument

与我之前的 相关,我试图创建一个函数 present() 来检查可选参数是否存在。但是,下面的代码

proc present( x ) { return x.type != void; }

proc test( a: ?T = _void )
{
    writeln();
    writeln( "test| a = ", a );
    writeln( "test| condition    = ", a.type != void );
    writeln( "test| present( a ) = ", present( a ) );

    if present( a )       // error (Line 1)
    // if a.type != void  // works (Line 2)
    {
        a = 10;
    }
}

// no optional arg
test();

// pass an optional array
var arr: [1..5] int;
test( a = arr );

writeln();
writeln( "main| arr = ", arr );

给出编译时错误

mytest.chpl:3: In function 'test':
mytest.chpl:13: error: illegal lvalue in assignment
mytest.chpl:13: error: a void variable cannot be assigned

表示 a = 10; 行有问题。另一方面,如果我使用第 2 行而不是第 1 行,代码将按预期工作:

test| a = 
test| condition    = false
test| present( a ) = false

test| a = 0 0 0 0 0
test| condition    = true
test| present( a ) = true

main| arr = 10 10 10 10 10 

此外,如果我将第 1 行或第 2 行替换为 if isArray( a ),该代码也有效。这是否意味着我们需要让编译器明确知道当 a_void 时未到达行 a = 10;? (换句话说,present()是否不足以让编译器知道,因为测试条件是present()里面的"hidden"?)

Does this mean that we need to let the compiler explicitly know that the line a = 10; is not reached when a is _void? (In other words, is present() not sufficient to let the compiler know it because the test condition is "hidden" inside present()?)

是的,没错。编译器需要在编译时知道 if 的主体只有在参数不为空的情况下才应该被编译。将 x.type != void 检查放入该条件是一个合理的解决方案,但如果您想要一个函数来计算是否应该评估该条件,您可以这样做。只需将 present 标记为 param 函数 - 这意味着它 returns 一个应该在编译时已知的值。这是完整的示例:

proc present( x ) param { return x.type != void; }

proc test( a: ?T = _void )
{
    writeln();
    writeln( "test| a = ", a );
    writeln( "test| condition    = ", a.type != void );
    writeln( "test| present( a ) = ", present( a ) );

    if present( a )
    {
        a = 10;
    }
}

// no optional arg
test();

// pass an optional array
var arr: [1..5] int;
test( a = arr );

writeln();
writeln( "main| arr = ", arr );

如果您想了解更多关于该领域的语言设计,请参阅"The Param Return Intent" subsection in "Procedures" chapter section "Return Intents" of the language specification