Тестовая функция для проверки необязательного аргумента - PullRequest
0 голосов
/ 15 декабря 2018

В связи с моим предыдущим вопросом я попытался создать функцию 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 = 10; не достигнута, когда a равен _void?(Другими словами, present() недостаточно, чтобы сообщить об этом компилятору, потому что условие теста "скрыто" внутри present()?)

1 Ответ

0 голосов
/ 17 декабря 2018

Значит ли это, что нам нужно дать компилятору явно знать, что строка a = 10;не достигается, когда _void?(Другими словами, присутствует () недостаточно для того, чтобы компилятор знал это, потому что условие теста «скрыто» внутри функции present ()?)

Да, все верно.Компилятор должен знать во время компиляции, что тело этого if должно быть скомпилировано только в том случае, если аргумент не void.Установка проверки x.type != void в этом условном выражении является разумным решением, но если вы хотите иметь функцию для вычисления, если это условное условие должно быть оценено, вы можете сделать это.Просто отметьте present как функцию param - это означает, что она возвращает значение, которое должно быть известно во время компиляции.Вот полный пример:

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 );

Если вы хотите узнать больше о структуре языка в этой области, см. Подраздел «Намерение возврата параметра» в разделе главы «Процедуры».«Return Intents» спецификации языка .

...