當我在我的測驗中得到一個奇怪的結果時,我正在為 C 制作一個運算子優先級和關聯性表,為此 Perl 與先驗的奇怪行為相同。
**冪運算子是右關聯的,這意味著運算式從右到左計算。
它顯然可以正確使用算術運算式,但奇怪的是,它不會通過 print 函式呼叫產生預期的結果。
我希望這會輸出321
$ perl -E 'print("1") ** print("2") ** print("3"); say ""'
123
但它產生123
這也發生在用戶定義的函式中:
$ perl -E 'sub my_print { print $_[0] } my_print(1) ** my_print(2) ** my_print(3); say ""'
123
更詭異的是,
$ perl -E 'sub my_print { say $_[0]; $_[0] } say my_print(2) ** my_print(2) ** my_print(4);'
2
2
4
65536
當我們定義一個帶有print副作用的函式時,它也回傳一個值。算術運算式的結果具有正確的期望值,其計算順序由運算子關聯性定義,但print仍不符合運算子關聯性。
好像有2個評估順序。
- 評估的正常順序,由 AST 定義,演算法在它上面進行評估以評估它(或者更有可能在
man perlguts和中解釋的“評估順序通過”期間op.c)。 - 副作用或 I/O 的第二個評估順序,其中似乎將具有副作用的內置函式呼叫放入佇列中,這帶來了一個問題:它們以什么順序放置
我將假設它不是一個錯誤,而是一個特性。如果它是一個錯誤,它早就被發現了。
所以這帶來了我的實際問題: 這種行為的合理性是什么? 以及 它是如何實施的?. (意味著使用了哪些資料結構以及在哪個編譯時間階段會發生這種情況)。
如果我認為某處有一個 AST 級別的佇列是正確的,那么呼叫排隊的順序是什么?print
EDIT1: 作為一個額外的精度,我知道在 I/O 期間涉及佇列,但這并沒有改變 I/O 操作通常按程式的評估順序排隊的事實,而不是任意的從左到 -程式文本的正確順序。
uj5u.com熱心網友回復:
您混淆了運算元評估順序和運算子優先級/關聯性。
運算子關聯性決定了是否
X ** Y ** Z // 2 ** 2 ** 3, for example
方法
( X ** Y ) ** Z // ( 2 ** 2 ) ** 3 = 64
或者
X ** ( Y ** Z ) // 2 ** ( 2 ** 3 ) = 256
正如你提到的,**是右結合的,所以它意味著后者。
它與 , 和X相Y對于彼此計算的順序無關。只要和在 之前進行計算,無論這四個運算式的計算順序如何,上面都會產生相同的結果。ZY ** ZYZY ** Z
可以得出一些結論。如前所述,Y顯然Z需要先評估Y ** Z。但是沒有這樣的要求[1] ,并且在檔案[2]中沒有相反的明確宣告,可以按照編譯器選擇的順序對運算子進行評估。
另一個例子是短路運算子必須先評估其左側運算元,然后再評估其右側運算元。
逗號運算子保證按順序評估每個運算元。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/461349.html
