Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 它是否破坏了对象的不变性?_Php_Class_Immutability - Fatal编程技术网

Php 它是否破坏了对象的不变性?

Php 它是否破坏了对象的不变性?,php,class,immutability,Php,Class,Immutability,我在读这篇文章: 并且遇到了一个例子,所以它是完美的不可变类: class Immutable { private $skater, $trick; public function __construct($skater, $trick) { $this->skater = $skater; $this->trick = $trick; } public function getSkater() {

我在读这篇文章:

并且遇到了一个例子,所以它是完美的不可变类:

class Immutable {
    private $skater, $trick;

    public function __construct($skater, $trick) {
        $this->skater = $skater;
        $this->trick = $trick;
    }

    public function getSkater() {
        return $this->skater;
    }

    public function getTrick() {
        return $this->trick;
    }
}
到目前为止还不错。但不易碎,如文章所述:

$x = new Immutable('Hawk', 'Frontside 540');
$x->__construct('Song', 'Darkslide');
它被改写成这样:

class Immutable {
    private $skater, $trick;
    private $mutable = true;

    public function __construct($skater, $trick) {
        if (false === $this->mutable) {
            throw new \BadMethodCallException('Constructor called twice.');
        }
        $this->skater = $skater;
        $this->trick = $trick;
        $this->mutable = false;
    }

    public function getSkater() {
        return $this->skater;
    }

    public function getTrick() {
        return $this->trick;
    }
}

但是现在更改
mute
值本身会破坏不变性,对吗?:)

否,它不会,因为该值仅在构造函数中设置,以后从未更改。所以它符合不变性的定义。我会将
$mutable
重命名为
$isCreated
或其他名称,因为您无法使用此属性更改类的可变属性,我认为它的命名有误导性

但是,在某种程度上,PHP中的对象不变性根本不可能实现,因为:

不变性并不意味着存储在计算机内存中的对象是不可写的。相反,不变性是一种编译时构造,它指示程序员可以通过对象的正常接口做什么,而不一定是绝对可以做什么

(来源:)

由于PHP中没有“编译时”,并且
$mutable
属性是在运行时计算的,因此它似乎从一开始就违反了这个概念

在另一个层面上,使用相同的引语,“普通接口”将是您的第一个示例所代表的。直接调用构造函数方法而不是通过
new
调用构造函数方法完全超出了正常使用范围。因此,您可以说,根据“通过普通接口”的约定,属性没有设置器的类已经是不可变的


基本上,您是在问一个学术问题,但试图解决一个现实世界的问题,即绝对确定对象的属性在实例化后在任何情况下都不能更改。但是“不变性”的概念并不适用。

不,它不适用,因为该值仅在构造函数中设置,以后从未更改。所以它符合不变性的定义。我会将
$mutable
重命名为
$isCreated
或其他名称,因为您无法使用此属性更改类的可变属性,我认为它的命名有误导性

但是,在某种程度上,PHP中的对象不变性根本不可能实现,因为:

不变性并不意味着存储在计算机内存中的对象是不可写的。相反,不变性是一种编译时构造,它指示程序员可以通过对象的正常接口做什么,而不一定是绝对可以做什么

(来源:)

由于PHP中没有“编译时”,并且
$mutable
属性是在运行时计算的,因此它似乎从一开始就违反了这个概念

在另一个层面上,使用相同的引语,“普通接口”将是您的第一个示例所代表的。直接调用构造函数方法而不是通过
new
调用构造函数方法完全超出了正常使用范围。因此,您可以说,根据“通过普通接口”的约定,属性没有设置器的类已经是不可变的


基本上,您是在问一个学术问题,但试图解决一个现实世界的问题,即绝对确定对象的属性在实例化后在任何情况下都不能更改。但是“不变性”的概念并不适用。

只要您的不可变类只接受基本数据类型(如string、int、float、bool),您的类就应该是相当不可变的。但一旦你传递了对象或流,它就不是一成不变的。即使使用值对象,也不容易获得真正的不可变对象。

只要不可变类只接受基本数据类型(如字符串、int、float、bool),那么类应该是相当不可变的。但一旦你传递了对象或流,它就不是一成不变的。即使使用值对象,也不容易获得真正的不可变对象。

以下两者之间没有根本区别:

  private $mutable = true;
然后(在施工时)将其更改为
false
,然后:

 private $skater
然后在以后(施工时)将其更改为其他内容。当您不设置初始值时,您所说的是:

private $skater = null;
在设置值之前,您可以通过执行
var\u dump($this->skater)
来轻松检查这一点,它将显示
null
。因此,在第一个示例中,实际上您已经在将null值更改为其他值。那么,在构造时更改
null
和更改
false
之间到底有什么区别呢


你是否认为不可改变是一种看法。PHP中唯一不变的是常量。

以下两者之间没有根本区别:

  private $mutable = true;
然后(在施工时)将其更改为
false
,然后:

 private $skater
然后在以后(施工时)将其更改为其他内容。当您不设置初始值时,您所说的是:

private $skater = null;
在设置值之前,您可以通过执行
var\u dump($this->skater)
来轻松检查这一点,它将显示
null
。因此,在第一个示例中,实际上您已经在将null值更改为其他值。那么,在构造时更改
null
和更改
false
之间到底有什么区别呢


你是否认为不可改变是一种看法。PHP中唯一不可变的是常量。

这是我今年听到的最奇怪的事情<代码>等级纬度(浮动$lat);类经度(浮动$lon);类点(纬度$lat,经度$lon);上课时间(整数$unixTime);类位置(点$位置,时间$时间)。只要对象的方法不改变对象的状态,它就是不可变的。我想知道你所说的“获得一个真正的不可变对象并不容易”是什么意思。@emix你知道引用是如何工作的吗?什么是“不想要的副作用”吗?这是我今年听到的最奇怪的事情<代码>等级纬度(浮动$la