5

我正在编写一个搜索例程,其中未定义和零都是有效结果。我正在返回一个二元素数组,($result, $answer)因为我没有“未定义但真实”的值。它工作正常,但有点笨拙。一堂课似乎有点矫枉过正。

这样的事情是否存在或可以以某种方式伪造?我在想诸如0E0把戏之类的事情。

更多细节。这是我想要的用户界面。当前例程返回两个值,结果(是否找到键)和一个值(如果找到)。

my $result = search_struct($key, $complex_data_structure);
if ($result) {
    print "A result was found for $key!  Value is: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}
4

4 回答 4

8

您可以只返回对结果的引用。返回undef无结果,\( undef )文字未定义结果,\( whatever )任何其他结果。然后调用者就可以使用$$result(确定$result定义后)。

于 2012-10-08T14:25:16.897 回答
5

不,但是有很多方法可以返回三个状态。

解决方案 1

  • 空列表 ( return;)
  • 未定义 ( return undef;)
  • 字符串 ( return "foo";)

my $found = my ($result) = search_struct($key, $data);
if ($found) {
    print "$key: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}

标量上下文中的列表赋值计算为其右侧返回的元素数。

解决方案 2

  • 错误 ( return undef;)
  • 引用未定义 ( return \undef;)
  • 引用字符串 ( return \"foo";)

my $result = search_struct($key, $data);
if ($result) {
    print "$key: ", $$result // "Undefined!", "\n";  # Note change here!
}
else {
    print "Sorry, no result was found for $key.\n";
}

解决方案 3

  • 错误 ( return 0;)
  • 真,且 undef ( return (1, undef);)
  • 真,字符串 ( return (1, "foo");)

my ($found, $result) = search_struct($key, $data);
if ($found) {
    print "$key: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}

解决方案 4

  • 错误 ( return 0;)
  • 是的,undef 作为参数返回 ( $_[2] = undef; return 1;)
  • 是的,字符串作为参数返回 ( $_[2] = "foo"; return 1;)

my $found = search_struct($key, $data, my $result);
if ($found) {
    print "$key: ", $result // "Undefined!", "\n";
}
else {
    print "Sorry, no result was found for $key.\n";
}

顺便说一句,我会将数据结构作为第一个参数传递,将键作为第二个参数传递。更像是面向对象编程。

于 2012-10-08T16:33:01.553 回答
2

您可能会在一个列表(不是数组)中返回您的答案:空列表表示未找到结果,否则返回一个元素列表((undef,)($some_answer,))。

它仍然相当笨拙,但是:

if (my ($answer) = the_function()) { # note parentheses
  process_answer($answer);  # might be undef, false, etc.
} else {
  no_results_found();
}
于 2012-10-08T15:41:34.877 回答
0

“未定义”如何也是“真实”?你为什么想要这样的构造?您是否没有意识到,对于返回未定义输入的函数,这样的结果也不应该是“真”。

但是,从 Perl 5.10 开始,这是谓词 not-a-defined-false:

if ( possibly_undefined() // 1 ) { 
}

但我认为零但真实实际上更适合查找功能。

my ( $value ) 
    = map  { $repos->get( $_ ) } 
      grep { $_ } 
      $repos->find( $lookup_criteria )
    ;

函数中的布尔值find代表问题“我找到了吗?” 该索引代表“在什么索引?”的问题。如果找不到索引,则返回''or undef。零但真实的意思是“我在第一个索引处找到它”。

但是,您始终可以使用您可能想要的任何布尔和整数解释来创建一个类。下面的类定义了一个对象,该对象可以在整数上下文中定义为整数,并且在测试数字是否为奇数时为 false:

package Odd; 
use strict;
use warnings;
use overload qw<bool boolean_result 0+ value fallback 1>;
sub new { return bless do { \( my $v = $_[1] ) }, $_[0]; }
sub boolean_result { return ${ $_[0] } % 2; }
sub value          { return ${ $_[0] }; }
sub set_value      { ${ $_[0] } = $_[1]; return $_[0]; }

package main;
use strict;
use warnings;
use Test::More;
my $odd = Odd->new( 1 );
is( $odd + 0, 1 );
is( !$odd, '' );
is( !!$odd, 1 );
my $even = Odd->new( 2 );
is( $even + 0, 2 );
is( !$even, 1 );
is( !!$even, '' );
done_testing();
于 2012-10-08T15:03:10.450 回答