9

タイトルがどうあるべきかわかりませんが、コードはそれをよりよく説明するはずです:

class Group {
    private $number = 20;

    public function __toString() {
        return "$this->number";
    }
}

$number = new Group();
echo $number, PHP_EOL;
echo ++ $number, PHP_EOL;

echo PHP_EOL;

$number = "20";
echo $number, PHP_EOL;
echo ++ $number, PHP_EOL;

echo PHP_EOL;

$number = 20;
echo $number, PHP_EOL;
echo ++ $number, PHP_EOL;

出力:

20
20              <--- Expected 21

20
21

20
21

なぜ私が20代わりに得たの21ですか?それでも、以下のコードは機能します。

$i = null ;
echo ++$i ; // output 1

Groupを実装するオブジェクトであることはわかって__toString++ます。__toStringthrow an error

4

5 に答える 5

12

操作が発生する順序は重要です。

  1. 変数はオブジェクトとしてフェッチされ、整数 (またはその他のもの) にキャストされません。

  2. この++演算子は のlval(long 値) をインクリメントしますzvalが、通常は他に何もしません。オブジェクト ポインタは同じままです。internalは、最初に型をチェックするオブジェクトへのポインタを持つ(fast_)increment_functionで呼び出されます。zvalオブジェクトの場合は何もしません。そのため、 yourzvalがオブジェクトの場合、操作を行わないのと同じくらい便利です。これは警告を出力しません。

  3. その場合にのみ、echo 命令が引数に対して文字列キャストを実行します。__toStringメソッドが呼び出され、 が返されます20

  4. 20が出力されます。

于 2013-05-04T16:52:24.037 に答える
9

少しのコードで質問に答えます。

$number = new Group();
echo gettype($number);

$number = "20";
echo gettype($number);

$number = 20;
echo gettype($number);

結果として

object
string
integer

3 つのケース:

  • オブジェクトに対して整数演算を実行できないため、コードが期待どおりに動作しません。メソッドは__toString、実際の出力が計算される非常に遅く呼び出されます。これは、数学演算を実行しようとして失敗した後です。
  • PHP が内部的に文字列を数値に変換するため、文字列を使って計算することができます。
  • 明らかに、整数で計算できます

ボーナス:

これはうまくいきます:

$number = new Group();
echo 1 + "$number"; // 21

オブジェクトを文字列に変換し、それを数学演算の数値に変換できます。

于 2013-05-04T14:36:18.717 に答える
2

次のように変数の名前を変更するだけで、より明確になると思います。

class Group {
    private $number = 20;

    public function __toString() {
        return "$this->number";
    }
}

$group = new Group();
echo $group;//print 20 as per your __toString function

++ $group;

これで明らかなように思えます: group 型のオブジェクトに対して '++' 演算子を実行するにはどうすればよいでしょうか??

于 2013-05-04T14:43:46.590 に答える
0

これは実際には、あなたが思っているよりも実現可能です。次のように、もう少し型キャストを行う必要があります。

<?php

class Group {
private $number = 20;

    public function __toString() {
        return (string) $this->number; // replace "" w/string cast
    }
}

$number = (int)(string) new Group();
echo $number, PHP_EOL;
echo ++$number, PHP_EOL;

もちろん、魔法の __toString() で文字列キャストを使用する必要はありませんが、個人的には、引用符を見るよりもそのようにコードを読むことを好みますが、それは単なるスタイル上の好みだと思います。

新しく作成されたオブジェクトを文字列としてキャストすると、魔法の __toString メソッドが自動的に実行され、数値文字列が返されます。これを int にキャストすると、数値を表示し、インクリメントして、再度表示することができます。

ちなみに、++ と $number の間のスペースは問題ありません。C などの他の言語で慣れている b/c で閉じました。

于 2013-11-08T04:48:57.770 に答える