简体   繁体   English

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

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

It seems similar to write:它似乎类似于写:

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

or或者

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

What is the better way to accomplish this: via const or via state ?实现此目的的更好方法是什么:通过const或通过state

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

UPD UPD
At this sub I do not change pointer togeoip database, so it should be const .在这个 sub 我不改变指针到geoip 数据库,所以它应该是const But I not want recreate object each time when sub is called (this is slow).但是我不想每次调用 sub 时都重新创建 object (这很慢)。 So I suppose it will be faster to use state , despite pointer is not changed.所以我想使用state会更快,尽管指针没有改变。

It seems it should be const state $ip_cc_database看来应该是const state $ip_cc_database

They do not do the same thing.他们不做同样的事情。

  • state declares a variable that will only be initialized the first time you enter the function. state声明了一个变量,该变量仅在您第一次进入 function 时才会被初始化。 It's mutable though, so you can change its value, but it will keep the value between calls to the same function.虽然它是可变的,所以你可以改变它的值,但它会在调用相同的 function 之间保持值。 This program would for example print 78 and 79 :例如,该程序将打印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 declares an immutable (readonly) variable that, if declared in a function, would be reinitialized every time the function is called. const声明一个不可变(只读)变量,如果在 function 中声明,则每次调用 function 时都会重新初始化该变量。

If you want a value that is constant, then you should use something like Const::Fast .如果你想要一个恒定的值,那么你应该使用类似Const::Fast的东西。

But if you want a value that can be changed, but which retains its value between calls to a function, then you need a state variable .但是,如果您想要一个可以更改的值,但在调用 function 之间保留其值,那么您需要一个state 变量

So running, this:所以运行,这个:

sub test {
  state $x = 1;

  say $x++;
}

test() for 1 .. 10;

Gives this:给出了这个:

1
2
3
4
5
6
7
8
9
10

But running this:但是运行这个:

use Const::Fast;

sub test {
  const my $x, 1;

  say $x++;
}

test() for 1 .. 10;

Gives a runtime error:给出运行时错误:

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

As @TedLyngmo points out in a comment to your OP, const state is not valid Perl.正如@TedLyngmo 在对您的 OP 的评论中指出的那样, const state无效 Perl。 const is a pragma, so works at compile time, while state is a runtime construct. const是一个编译指示,因此在编译时起作用,而state是一个运行时构造。

In terms of your efficiency requirement, that the GeoIP2::Database::Reader constructor is called only once, either will work.就您的效率要求而言, GeoIP2::Database::Reader构造函数只调用一次,两者都可以。 If you further want it to be read-only so that you cannot inadvertently invalidate the reference, you can still use both.如果您进一步希望它是只读的,这样您就不会无意中使引用无效,您仍然可以同时使用两者。 const does it for you automatically, but you can duplicate that behavior with state with a layer of indirection: 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();
    ...
}

The answer to your question about when to use one over the other is a bit more nuanced.关于何时使用一个而不是另一个的问题的答案有点微妙。

The real difference between the two approaches is when the constructor is called.这两种方法的真正区别在于调用构造函数的时间。 Using const it's during the compile phase, with state it's during runtime.使用const是在编译阶段,使用state是在运行时。

If you're application always calls get_ip_country , and you don't care about amortizing startup costs over the lifetime of the process, const is simpler.如果您的应用程序总是调用get_ip_country ,并且您不关心在进程的生命周期内摊销启动成本,则const更简单。

However, if you don't always call get_ip_country , and creating the GeoIP2::Database::Reader object is expensive, then using state means you only pay for that cost if you need it.但是,如果您不总是调用get_ip_country ,并且创建GeoIP2::Database::Reader object 的成本很高,那么使用state意味着您只需在需要时支付该成本。

There's also the user experience to consider.还需要考虑用户体验。 If your program is interactive or if it starts generating output before you need to call get_ip_country , delaying creating the object until its actually needed means your program doesn't just sit there seemingly doing nothing until all of the startup has completed.如果您的程序是交互式的,或者如果它在您需要调用get_ip_country之前开始生成 output ,则延迟创建 object 直到它真正需要它意味着您的程序不会只是坐在那里看似什么都不做,直到所有的启动完成。

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

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