在PHP中模拟值类型结构类

时间:2009-09-28 12:23:11

标签: php types structure type-safety

有没有办法在PHP中模拟结构类?即一个通过值而不是通过引用传递的类,因此它仍然可以是类型提示......

如果是这样,可以使用哪些不同的技术?什么是最好的技术?

如果这是可能的,你显然可以为PHP创建一个完全类型安全的层,是否有这样的层?有没有人有这方面的经验?

4 个答案:

答案 0 :(得分:1)

我认为最简单的方法是像java那样做 - 让你的值类是不可变的,让所有“修改”方法改为返回一个新对象。

答案 1 :(得分:1)

我认为只有使用PHP代码才能实现这一目标。

你无法控制PHP函数如何处理参数,我不知道如何确保一切都按照你想要的方式处理,而不必更改PHP二进制文件和模块中的(低级)代码

但这会很酷:)

答案 2 :(得分:1)

对象始终通过引用传递。将它们作为副本传递的唯一方法是明确使用clone关键字(是的,无处不在)。

我的建议是使用一个数组,它们是值类型,因此总是被复制。由于您可以将它用作关联数组(例如string - > value),因此它也可能是一个对象。当然,缺点是你不能使用方法(但这就像一个结构,所以你可能会对此感到满意)。但是,没有办法强制实施类型安全。

但是老实说,尽管你有所有要求,但听起来PHP并不是你的语言。

答案 3 :(得分:1)

我正在玩匿名的建议,让对象的任何突变都返回一个新对象,这样可行,但这很尴尬。

<?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';

最后,将变量设为私有并且不提供变更器可能更容易,因此更改变量的“枚举”值的唯一方法是创建一个新变量:

echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");