它似乎類似于寫:
use Const::Fast;
const $xx, 77;
sub test {
do_something_with( $xx );
}
或者
sub test {
state $xx = 77;
do_something_with( $xx );
}
完成此任務的更好方法是什么: viaconst或 via 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 時都重新創建物件(這很慢)。所以我想它會更快使用state,盡管指標沒有改變。
好像應該是const state $ip_cc_database
uj5u.com熱心網友回復:
他們不做同樣的事情。
state宣告一個變數,它只會在你第一次進入函式時被初始化。雖然它是可變的,所以你可以改變它的值,但它會在呼叫同一個函式之間保持這個值。該程式將例如列印78和79:sub test { state $xx = 77; # initialization only happens once print $xx . "\n"; # step the current value and print it } test; # 78 test; # 79const宣告一個不可變(只讀)變數,如果在函式中宣告,則每次呼叫函式時都會重新初始化。
uj5u.com熱心網友回復:
如果你想要一個恒定的值,那么你應該使用類似Const::Fast的東西。
但是,如果您想要一個可以更改的值,但在呼叫函式之間保留其值,那么您需要一個狀態變數。
所以運行,這個:
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.
uj5u.com熱心網友回復:
正如@TedLyngmo 在對您的 OP 的評論中指出的那樣,const statePerl 無效。 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物件的成本很高,那么使用state意味著您只需在需要時支付該成本。
還需要考慮用戶體驗。如果您的程式是互動式的,或者如果它在您需要呼叫之前開始生成輸出get_ip_country,則延遲創建物件直到它真正需要它意味著您的程式不會只是坐在那里看似什么都不做,直到所有的啟動完成。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425571.html
