سؤال

هل هناك أي طريقة لمحاكاة فئة هيكل في PHP؟ أي فصل يمر حسب القيمة وليس بالرجوع إليها، لذلك لا يزال بإمكانه تلميح ...

وإذا كان الأمر كذلك، ما هي التقنيات المختلفة التي يمكن استخدامها؟ ما هي أفضل تقنية؟

إذا كان ذلك ممكنا، فيمكنك إنشاء طبقة آمنة كاملة النوع بالكامل ل PHP، هل توجد مثل هذه الطبقات؟ أي شخص لديه أي خبرة في هذا؟

هل كانت مفيدة؟

المحلول

يتم تمرير الكائنات دائما بالرجوع إليها. الطريقة الوحيدة لجعلها تمر كنسخة هي استخدام صريح clone الكلمة الرئيسية (نعم، في كل مكان).

ستكون توصيتي هي استخدام مجموعة، والتي هي أنواع القيمة وبالتالي نسخ دائما. نظرا لأنك يمكنك استخدامها كصفيف مشترك (مثل السلسلة -> القيمة)، فقد يكون ذلك كائنا. الجانب السلبي، بالطبع، لا يمكنك استخدام الأساليب (ولكن هذا مثل الهيكل حتى تكون سعيدا بهذا). لا توجد طريقة لفرض سلامة النوع، ولكن.

ولكن مع كل الاحتياجات الخاصة بك يبدو أن PHP ليس من نوع لغتك، أن نكون صادقين.

نصائح أخرى

أعتقد أن أسهل طريقة هي أن تفعل ذلك مثل Java لا - هل تكون فئات القيمة غير قابلة للتطبيق، واسمحوا جميع طرق "التعديل" بإرجاع كائن جديد بدلا من ذلك.

لا أعتقد أنه يمكنك تحقيق هذا الهدف، فقط مع رمز PHP.

ليس لديك أي سيطرة على كيفية معالجة PHP معلمات المعلمات، ولا أرى كيف يمكنك التأكد من معالجة كل شيء بالطريقة التي تريدها، دون الحاجة إلى تغيير الرمز (المستوى الأدنى) في PHP Binary and Modules.

سيكون رائعا جدا، على الرغم من :)

كنت ألعب مع اقتراح مجهول لجعل أي طفرات للعودة إلى كائن جديد، وهذا يعمل، لكنه محرج.

<?php
class FruityEnum {
    private $valid = array("apple", "banana", "cantaloupe");
    private $value;

    function __construct($val) {
        if (in_array($val, $this->valid)) {
            $this->value = $val;
        } else {
            throw new Exception("Invalid value");
        }
    }

    function __set($var, $val) {
        throw new Exception("Use set()!!");
    }
    function set(FruityEnum &$obj, $val) {
        $obj = new FruityEnum($val);
    }

    function __get($var) { //everything returns the value...
        return $this->value;
    }
    function __toString() {
        return $this->value;
    }
}

والآن لاختبارها:

function mutate(FruityEnum $obj) { // type hinting!
    $obj->set($obj, 'banana');
    return $obj;
}

$x = new FruityEnum('apple');
echo $x; // "apple"
$y = mutate($x);
echo  $x // still "apple"
    . $y // "banana"

يعمل، ولكن عليك استخدام طريقة غريبة لتغيير الكائن:

$obj->set($obj, 'foo');

الطريقة الأخرى الوحيدة التي يمكن أن أفكر فيها للقيام بذلك ستكون استخدام __set() الطريقة، لكن ذلك كان أسوأ. كان عليك القيام بذلك، وهو أمر مربك دموي.

$obj = $obj->blah = 'foo';

في النهاية، ربما من الأسهل إجراء المتغيرات الخاصة وتقديم أي مشارب، وبالتالي فإن الطريقة الوحيدة لتغيير قيمة "Enum" المتغيرة هي إنشاء واحدة جديدة:

echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top