28

Perlでは、次の違いは何ですか

$status = 500;

$status = '500';
4

9 に答える 9

39

あまりない。どちらも に 500 を割り当て$statusます。使用される内部フォーマットは最初は異なります (IV と PV、UTF8=0) が、Perl にとっては重要ではありません。

ただし、ストレージ形式の選択に基づいて異なる動作をするものがありますが、そうすべきではありません。ストレージ形式の選択に基づいて、

  • JSON は、引用符を使用するかどうかを決定します。
  • DBI は、パラメータに使用すべき SQL タイプを推測します。
  • ビット演算子 ( &|および^) は、オペランドが文字列かどうかを推測します。
  • openおよびその他のファイル関連のビルトインは、UTF-8 を使用してファイル名をエンコードするかどうかを指定します。(バグ!)
  • 一部の算術演算は、負のゼロを返すかどうかを返します。
于 2013-06-27T00:49:27.510 に答える
21

すでに @ikegami はあまり話していませんでした。しかし、ここよりも覚えておいてください。

$ perl -E '$v=0500; say $v'

出力320(8 進数 0500 の 10 進数値)、および

$ perl -E '$v="0500"; say $v'

何を印刷するか

0500

$ perl -E '$v=0900; say $v'

エラーで死ぬもの:

Illegal octal digit '9' at -e line 1, at end of line
Execution of -e aborted due to compilation errors.

perl -E '$v="0300";say $v+1'

版画

301

しかし

perl -E '$v="0300";say ++$v'

版画

0301

と同様0x\d+、例えば:

$v = 0x900;
$v = "0x900";
于 2013-06-27T01:22:13.350 に答える
19

$var文字列または数値を操作するときに、異なるフレーバーを持ついくつかの演算子のいずれかを使用する場合にのみ違いがあります。

$string = '500';
$number = 500;
print $string & '000', "\n";
print $number & '000', "\n";

出力:

000
0
于 2013-06-27T02:18:59.073 に答える
6

1 つ目は数値 (499 から 501 までの整数) です。2 番目は文字列 (文字 '5'、'0'、および '0') です。それらの間に違いがないというのは真実ではありません。一方が他方にすぐに変換されるというのは真実ではありません。文字列は必要に応じて数値に変換され、その逆も同様であり、変換はほとんど透過的ですが、完全ではありませ

回答When does the difference between a string and a number matter in Perl 5は、それらが同等でないいくつかのケースをカバーしています:

  • ビット単位の演算子は数値を数値として扱いますが (各数値のバイナリ表現のビットを操作します)、文字列を文字単位で扱います (各文字列の各文字のビットを操作します)。
  • JSON モジュールは、数値であっても文字列を文字列 (引用符付き) として出力しますが、数値は数値として出力します。
  • 非常に小さい数または非常に大きい数は、予想とは異なる方法で文字列化される可能性がありますが、文字列はすでに文字列であり、文字列化する必要はありません。つまり、 if$x = 1000000000000000$y = "1000000000000000"then $x は に文字列化される可能性があり1e+15ます。変数をハッシュ キーとして使用すると文字列化されるため、$hash{$x}$hash{$y}が異なるハッシュ スロットになる可能性があります。
  • スマートマッチ ( ~~) および given/when 演算子は、数値引数を数値文字列とは異なる方法で扱います。とにかくこれらの演算子を避けるのが最善です。
于 2013-06-27T16:18:05.607 に答える
3

これは何が起こっているかを完全に示していると思います。

$ perl -MDevel::Peek -e 'my ($a, $b) = (500, "500");print Dump $a; print Dump $b; $a.""; $b+0; print Dump $a; print Dump $b'
SV = IV(0x8cca90) at 0x8ccaa0
  REFCNT = 1
  FLAGS = (PADMY,IOK,pIOK)
  IV = 500
SV = PV(0x8acc20) at 0x8ccad0
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x8c5da0 "500"\0
  CUR = 3
  LEN = 16
SV = PVIV(0x8c0f88) at 0x8ccaa0
  REFCNT = 1
  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
  IV = 500
  PV = 0x8d3660 "500"\0
  CUR = 3
  LEN = 16
SV = PVIV(0x8c0fa0) at 0x8ccad0
  REFCNT = 1
  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
  IV = 500
  PV = 0x8c5da0 "500"\0
  CUR = 3
  LEN = 16

各スカラー ( SV) は、文字列 ( PV) または数値 ( IV) 表現を持つことができます。数値演算で文字列表現のみの変数を使用し、文字列演算で数値表現のみの変数を使用すると、両方の表現が得られます。正確には、別の数値表現である浮動小数点表現 ( NV) も存在する可能性があるため、スカラー値の表現には 3 つの可能性があります。

于 2013-07-28T07:25:36.113 に答える
3

内部的には異なります:)

($_ ^ $_) ne '0' ? print "$_ is string\n" : print "$_ is numeric\n" for (500, '500');

出力:

500 is numeric
500 is string
于 2013-06-27T09:36:15.680 に答える
2

この質問にはすでに多くの回答がありますが、混乱している初心者のために試してみます。

my $foo = 500;
my $bar = '500';

そのままでは、実際的な目的のために、それらは「同じ」です。興味深いのは、演算子を使用する場合です。例えば:

print $foo + 0;

output: 500

「+」演算子は、左に数値、右に数値を表示します。どちらも小数であるため、答えは 500 + 0 => 500 です。

print $bar + 0;

output: 500

同じ出力で、演算子は、左が 10 進数の整数、右がゼロのような文字列を確認します。したがって、500 + 0 => 500 となります。

しかし、違いはどこにありますか?使用するオペレーターによって異なります。オペレーターは何が起こるかを決定します。例えば:

my $foo = '128hello';
print $foo + 0;
output: 128

この場合、C の atoi() のように動作します。左から順に最大の数値部分を取り、それを数値として使用します。数字がない場合は、0 として使用します。

条件付きでこれを処理する方法は?

my $foo = '0900';
my $bar = 900;
if( $foo == $bar)
{print "ok!"}
else
{print "not ok!"}

output: ok!

== は、両方の変数の数値を比較します。警告を使用すると、文字列で == を使用すると文句を言いますが、それでも強制しようとします。

my $foo = '0900';
my $bar = 900;
if( $foo eq $bar)
{print "ok!"}
else
{print "not ok!"}

output: not ok!

eq は、文字列が等しいかどうかを比較します。

于 2013-07-27T22:36:50.280 に答える