国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

PHP 5.6新特性之一:內部操作符重載

canopus4u / 785人閱讀

摘要:轉載自我的博客在眾多的新特性中,我覺得這是最神奇甚至是詭異的一個,如果有不理解這個概念的朋友,可能連它的說明都看不懂。在這個例子中操作符被重載為,操作符被重載為。再重載成操作符,以后咋跟蹤代碼。。。

  

轉載自我的博客:http://70.io/2014/03/php-5_6-internal-operator-overloading

在眾多php 5.6的新特性中,我覺得這是最神奇甚至是詭異的一個,如果有不理解這個概念的朋友,可能連它的說明都看不懂 https://wiki.php.net/rfc/operator_overloading_gmp。

首先要說明的是,這個重載不影響userland,也就是我們不用關心它是怎么重載的,只用關心怎么使用,它的實現是在php內核代碼中。

在上面的php說明網址中,它舉了一個對gmp_*模塊重載后的例子

// 重載前的代碼
$result = gmp_mod(
    gmp_add(
        gmp_mul($c0, gmp_mul($ms0, gmp_invert($ms0, $n0))),
        gmp_add(
            gmp_mul($c1, gmp_mul($ms1, gmp_invert($ms1, $n1))),
            gmp_mul($c2, gmp_mul($ms2, gmp_invert($ms2, $n2)))
        )
    ),
    gmp_mul($n0, gmp_mul($n1, $n2))
);

// 重載后的代碼
$result = (
    $c0 * $ms0 * gmp_invert($ms0, $n0)
  + $c1 * $ms1 * gmp_invert($ms1, $n1)
  + $c2 * $ms2 * gmp_invert($ms2, $n2)
) % ($n0 * $n1 * $n2);

如果你會一點scala類似的語言,就能很好地理解了。在這個例子中+操作符被重載為gmp_add*操作符被重載為gmp_mull。以前的基于函數式的代碼讓很多算法上的細節無法展現出來,改成基于操作符的就很好理解了。

它是怎么實現的呢?讓我們來跟蹤一下這個patch修改的源代碼,https://github.com/php/php-src/pull/342/files。最好先關注Zend/zend_operators.c這個文件的修改,基本上邏輯就很清晰了,比如ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)這個函數,它處理了php中的加號+運算(前面帶+的兩行是這個patch增加的內容)

            default:
                if (!converted) {
 +                  ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB);
 +
                    zendi_convert_scalar_to_number(op1, op1_copy, result);
                    zendi_convert_scalar_to_number(op2, op2_copy, result);
                    converted = 1;

if(!converted)判斷了左右操作數還沒有轉換為number時候的處理,在以前是調用zendi_convert_scalar_to_number直接將其轉換為number然后再SUB,現在在前面加了個宏ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB),這個宏的實現細節是

#define ZEND_TRY_BINARY_OBJECT_OPERATION(opcode)                                                  
    if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation)) {                       
        if (SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, op2 TSRMLS_CC)) {  
            return SUCCESS;                                                                       
        }                                                                                         
    } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, do_operation)) {                
        if (SUCCESS == Z_OBJ_HANDLER_P(op2, do_operation)(opcode, result, op1, op2 TSRMLS_CC)) {  
            return SUCCESS;                                                                       
        }                                                                                         
    }

它先判斷左操作數是否為一個OBJECT,并且這個OBJECT內部定義了運算符操作的重載實現,如果是那么就調用這個handler來處理這次操作符運算,如果左操作數不符合這些條件,再對右操作數做一次這些判斷,基本上$a + $b你就可以理解為以下偽代碼

if ($a instanceof GMP && method_exists($a, "add")) {
    $a->add($b);
} else if ($b instanceof GMP && method_exists($b, "add")) {
    $b->add($a);
}

好吧,最后我來談談我的看法,之所以我對這個改進感到詭異是因為,它對一般的web開發基本沒啥用,其影響基本是很少用到的數學運算模塊。而且由于這個改進跟userland沒啥關系,所以我們在php代碼中也用不了,別指望你能像scala那樣在class里定義操作符的實現,這完全是兩碼事。

你只能指望這些模塊或者擴展的作者實現了,而且最后實現也沒有一個統一的標準,本來php的函數命名就夠混亂了。。。再重載成操作符,以后咋跟蹤代碼。。。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/20695.html

相關文章

  • php易錯筆記-類與對象,命名空間

    摘要:類與對象基本概念如果在之后跟著的是一個包含有類名的字符串,則該類的一個實例被創建。如果該類屬于一個名字空間,則必須使用其完整名稱。如果一個類被聲明為,則不能被繼承。命名空間通過關鍵字來聲明。 類與對象 基本概念 new:如果在 new 之后跟著的是一個包含有類名的字符串,則該類的一個實例被創建。如果該類屬于一個名字空間,則必須使用其完整名稱。 Example #3 創建一個實例 ...

    MartinHan 評論0 收藏0
  • PHP經驗總結 - 聊聊面向對象

    摘要:例如汽車這個名詞可以理解為汽車的總類,但這輛寶馬汽車則是一個具體的汽車對象。當在類成員方法內部調用的時候,可以使用偽變量調用當前對象的屬性。在面向對象中則被稱之為方法。 簡述 現在大伙都在講面向對象編程,但是我們也得先找著一個對象是不?不然怎么面向對象?怎么編程? --- 笑話一則,但是理不虧,要搞P面向對象編程,我們起碼要先搞懂對象(還有類)是什么?只有了解它,理解它,你才能駕馭它。...

    lpjustdoit 評論0 收藏0
  • PHP 7 值得期待的特性(上)

    摘要:然而,兩個重要的已經獲得通過,它們將帶來一些期望已久的內部與用戶層的一致性。綜合比較運算符我個人最喜歡的新增特性是綜合比較運算符,,也稱為飛船操作符。實際上,該操作符的工作方式與,或基本一致。 這是我們期待已久的 PHP 7 系列文章的第一篇。 或許你已經知道了,我在?PHP 5.0.0 時間軸?提的 RFC (Request For Comments)通過了, PHP 7 成為 PH...

    msup 評論0 收藏0
  • PHP 5.3、5.4、5.5、5.6 中的特性

    摘要:同時還支持簡寫的運算符,表示進行冪運算并賦值。對應的結構為和。為了達到一致性將添加函數。新增函數可用來返回數組中指定的一列。這種簡寫形式被稱為在起被默認開啟,在起總是可用。三元運算符可以簡寫省略中間的部分表達式,當為時返回,否則返回。 PHP 5.6 1、可以使用表達式定義常量 https://php.net/manual/zh/migration56.new-features.p...

    ysl_unh 評論0 收藏0
  • PHP 5.3、5.4、5.5、5.6 中的特性(7出來但是一樣有用)

    摘要:同時還支持簡寫的運算符,表示進行冪運算并賦值。為了達到一致性將添加函數。新增函數可用來返回數組中指定的一列。這種簡寫形式被稱為在起被默認開啟,在起總是可用。結構中可以用雙引號來聲明標識符了。 PHP 5.61、可以使用表達式定義常量 https://php.net/manual/zh/mig... 在之前的 PHP 版本中,必須使用靜態值來定義常量,聲明屬性以及指定函數參數默認值。 現...

    Shihira 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<