2016-03-17 2 views
2

Я хочу вернуть пустой массив , а не пустой .Как вернуть пустой массив/массив длиной 0 в perl?

У меня есть sub, который возвращает массив вещей. Я хочу быть в состоянии сделать это с ним:

my $count = scalar getArray(); 

Я сделал это так:

sub getArray { 
    if (!isGood()) { 
     return(); 
    } else { 
     my @array = calculateSomehow(); 
     return @array; 
    } 
} 
my $count = scalar getArray(); 

Я имел сярприз когда !isGood() и $count становится undef, не 0! После прочтения perlfaq4, я понимаю, что это происходит потому, что GetArray() вычисляется в скалярном контексте и, следовательно, список() оценивается как скаляр и scalar(()) является undef, а my @array; scalar(@array) 0.

Вопрос теперь становится: Как мне наиболее элегантно вернуть пустой массив , так что $count is 0, если !isGood()? Я только придумал:

# This is kind of kludgy: Dereference an anonymous array ref. Really? 
return @{[]}; 

или

# I use a temporary variable for this. Really? 
my @empty; 
return @empty; 

Не существует каких-либо очиститель/более элегантные способы возвращающий массив длины 0 (пустой массива) или некоторые другой способ сделать scalar getArray() оценить до 0?

+1

Вы обнаружили, что 'мой мой чистый пустяк' или более элегантный? – choroba

+0

Спасибо @choroba - да, я знаю! –

+2

подписчики всегда возвращают списки. – ysth

ответ

5

Это, вероятно, яснее, если вы просто вернуть массив в обоих случаях:

sub getArray { 
    my @array; 
    @array = calculateSomehow() if isGood(); 
    return @array; 
} 

Но изменить исходный код в минимальном пути, используйте wantarray.

if (!isGood()) { 
    return wantarray ?() : 0; 
} 
+8

'my ... if' имеет неопределенное поведение. – choroba

+0

@choroba Это меня поразило бы, если бы правда. Пожалуйста, предоставьте ссылку. – Sean

+0

Я думаю, что так оно и есть: сначала объявляет, затем вычисляет ... но что, если 'if' терпит неудачу? Что делать? Я считаю, что декларация идет независимо, и тогда она может зависеть от того, что делать дальше. У меня были подобные вещи. Я не могу сказать, что это строго «неопределенное поведение», хотя, не знаю. – zdim

0

возвращает ссылку, и вы можете получить размер массива (0, если пусто) в одном вызове, разыменовывая.

sub getArray { 
    # calculate ... 
    return [ @results ];  # @results may be empty 
} 

$rres = getArray(); 
my $count = @$rres;   # gives 0 if ref is to empty array 

my $cnt = @{ getArray() }; # or without storing the return 

Вы можете использовать scalar выше, если вы хотите, но вам не нужно. Это также подобно возврату указателя на массив (даже если пустой), если это то, что вы имели в виду, требуя «пустой массив».

Если вы хотите идти по этому пути, но выделить not-good

sub getArray { 
    return if !isGood(); # returns undef 
    # calculate ... 
    return [ @results ]; # scalar whether the list be empty or not 
} 

Использование context может помочь - вы либо получить массив (пустой список или нет), или 0 для скаляр

sub getArray { 
    if (!isGood()) { 
     return (wantarray) ?() : 0; 
    } 
    else { } # your code 
} 
my @results = getArray() # returns a list, possibly empty 
my $count = getArray(); # returns 0 
+0

Извините, zdim, @Sean избил вас! ;-) –

+0

@ PeterV.Mørch Я вижу это ... на 17 секунд ?? – zdim

+0

Оказалось, благодаря (легкой) поправке, в которой он нуждался ... он не – zdim

Смежные вопросы