繁体   English   中英

`state` 和 `const` 有什么区别?

[英]What is the difference between `state` and `const`?

它似乎类似于写:

use Const::Fast;
const $xx, 77;
sub test {
    do_something_with( $xx );    
}

或者

sub test {
    state $xx =  77;
    do_something_with( $xx );    
}

实现此目的的更好方法是什么:通过const或通过state

sub get_ip_country {
    my ($ip_address) = @_;
    my $ip_cc_database = GeoIP2::Database::Reader->new(file => '/etc/project/GeoLite2-Country.mmdb');
    ...
}

UPD
在这个 sub 我不改变指针到geoip 数据库,所以它应该是const 但是我不想每次调用 sub 时都重新创建 object (这很慢)。 所以我想使用state会更快,尽管指针没有改变。

看来应该是const state $ip_cc_database

他们不做同样的事情。

  • state声明了一个变量,该变量仅在您第一次进入 function 时才会被初始化。 虽然它是可变的,所以你可以改变它的值,但它会在调用相同的 function 之间保持值。 例如,该程序将打印7879
     sub test { state $xx = 77; # initialization only happens once print ++$xx. "\n"; # step the current value and print it } test; # 78 test; # 79
  • const声明一个不可变(只读)变量,如果在 function 中声明,则每次调用 function 时都会重新初始化该变量。

如果你想要一个恒定的值,那么你应该使用类似Const::Fast的东西。

但是,如果您想要一个可以更改的值,但在调用 function 之间保留其值,那么您需要一个state 变量

所以运行,这个:

sub test {
  state $x = 1;

  say $x++;
}

test() for 1 .. 10;

给出了这个:

1
2
3
4
5
6
7
8
9
10

但是运行这个:

use Const::Fast;

sub test {
  const my $x, 1;

  say $x++;
}

test() for 1 .. 10;

给出运行时错误:

Modification of a read-only value attempted at const_test line 12.

正如@TedLyngmo 在对您的 OP 的评论中指出的那样, const state无效 Perl。 const是一个编译指示,因此在编译时起作用,而state是一个运行时构造。

就您的效率要求而言, GeoIP2::Database::Reader构造函数只调用一次,两者都可以。 如果您进一步希望它是只读的,这样您就不会无意中使引用无效,您仍然可以同时使用两者。 const会自动为您执行此操作,但您可以使用state与间接层复制该行为:

sub ip_cc_database {
   state $db = GeoIP2::Database::Reader->new(file => '/etc/project/GeoLite2-Country.mmdb');
}
sub get_ip_country {
    my ($ip_address) = @_;
    my $ip_cc_database = ip_cc_database();
    ...
}

关于何时使用一个而不是另一个的问题的答案有点微妙。

这两种方法的真正区别在于调用构造函数的时间。 使用const是在编译阶段,使用state是在运行时。

如果您的应用程序总是调用get_ip_country ,并且您不关心在进程的生命周期内摊销启动成本,则const更简单。

但是,如果您不总是调用get_ip_country ,并且创建GeoIP2::Database::Reader object 的成本很高,那么使用state意味着您只需在需要时支付该成本。

还需要考虑用户体验。 如果您的程序是交互式的,或者如果它在您需要调用get_ip_country之前开始生成 output ,则延迟创建 object 直到它真正需要它意味着您的程序不会只是坐在那里看似什么都不做,直到所有的启动完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM