在PHP中模拟值类型结构类
有没有办法在PHP中模拟结构类?ie是一个通过值而不是引用传递的类,所以它仍然可以被类型暗示 如果是这样,可以使用哪些不同的技术?最好的技术是什么在PHP中模拟值类型结构类,php,types,structure,type-safety,Php,Types,Structure,Type Safety,有没有办法在PHP中模拟结构类?ie是一个通过值而不是引用传递的类,所以它仍然可以被类型暗示 如果是这样,可以使用哪些不同的技术?最好的技术是什么 如果这是可能的,您显然可以为PHP创建一个完全类型安全的层,有这样的层吗?有人有过这样的经验吗?我认为最简单的方法是像java那样做——让您的值类不可变,让所有“修改”方法返回一个新对象。我认为只有使用PHP代码才能实现这一目标 您无法控制PHP函数如何处理参数,我也不知道您如何确保一切都按您想要的方式处理,而不必更改PHP二进制和模块中的(低级)代
如果这是可能的,您显然可以为PHP创建一个完全类型安全的层,有这样的层吗?有人有过这样的经验吗?我认为最简单的方法是像java那样做——让您的值类不可变,让所有“修改”方法返回一个新对象。我认为只有使用PHP代码才能实现这一目标 您无法控制PHP函数如何处理参数,我也不知道您如何确保一切都按您想要的方式处理,而不必更改PHP二进制和模块中的(低级)代码
不过,这会很酷:)对象总是通过引用传递的。让它们作为副本传递的唯一方法是显式使用
clone
关键字(是的,无处不在)
我的建议是使用数组,数组是值类型,因此总是被复制的。因为您可以将其用作关联数组(例如字符串->值),所以它也可以是一个对象。当然,缺点是不能使用方法(但这就像一个结构,所以您可能会对此感到满意)。但是,没有办法强制执行类型安全性
但是,老实说,根据您的所有要求,PHP听起来似乎不是您喜欢的语言。我一直在玩弄anonymous的建议,让对象的任何变化都返回一个新对象,这是可行的,但很尴尬
<?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;
}
}
它可以工作,但您必须使用一种奇怪的方式来更改对象:
$obj->set($obj, 'foo');
我能想到的唯一其他方法是使用\uu set()
方法,但那更糟糕。你必须这么做,这让人很困惑
$obj = $obj->blah = 'foo';
最后,可能更容易将变量设置为私有,并且不提供任何变体,因此更改变量“enum”值的唯一方法是创建一个新的变量:
echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");
如果将其传递给函数,如何确保它传递的是副本而不是引用?或者每次你想传递克隆操作符时都必须使用它吗?它会传递一个引用,但这无关紧要——接收函数无论如何都不能修改它。换句话说,只要对象是不可变的,复制和引用之间的差异就消失了。将其放入数组可能是合理的,但是您不能再提示它了。。。你可以输入一个数组,但那不再是类型安全的了。。。恶性循环。。。我使用php已经有相当长的时间了,越来越多的我开始错过诸如类型安全之类的东西…很好的实验,尽管它产生的开销和使用克隆操作符一样多+1.
echo $obj; // "banana"
$obj = new FruityEnum("cantaloupe");