Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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
Oop 什么是不变性?我为什么要担心它?_Oop_Immutability - Fatal编程技术网

Oop 什么是不变性?我为什么要担心它?

Oop 什么是不变性?我为什么要担心它?,oop,immutability,Oop,Immutability,我读了几篇关于不变性的文章,但仍然没有很好地理解这个概念 我最近在这里做了一个线程,其中提到了不变性,但由于这本身就是一个主题,我现在正在做一个专门的线程 我在过去的线程中提到,我认为不变性是使对象只读并使其低可见性的过程。另一位成员表示,这与此无关。(a的一部分)使用不可变类/结构的示例,并使用只读和其他概念将其锁定 在这个例子中,状态的定义到底是什么?国家是一个我还没有真正掌握的概念 从设计指南的角度来看,不可变类必须是不接受用户输入并且只返回值的类 我的理解是,任何只返回信息的对象都应该是

我读了几篇关于不变性的文章,但仍然没有很好地理解这个概念

我最近在这里做了一个线程,其中提到了不变性,但由于这本身就是一个主题,我现在正在做一个专门的线程

我在过去的线程中提到,我认为不变性是使对象只读并使其低可见性的过程。另一位成员表示,这与此无关。(a的一部分)使用不可变类/结构的示例,并使用只读和其他概念将其锁定

在这个例子中,状态的定义到底是什么?国家是一个我还没有真正掌握的概念

从设计指南的角度来看,不可变类必须是不接受用户输入并且只返回值的类


我的理解是,任何只返回信息的对象都应该是不可变的和“锁定”的,对吗?因此,如果我想用这一方法返回专用类中的当前时间,我应该使用引用类型,因为它将处理该类型的引用,因此我受益于不可变性。

简单地说:一旦创建了不可变对象,就无法更改该对象的内容。Net不可变对象的示例有字符串和Uri

修改字符串时,只需获得一个新字符串。原始字符串不会更改。Uri只有只读属性,没有可用于更改Uri内容的方法

不可变对象很重要的情况多种多样,在大多数情况下都与安全性有关。Uri就是一个很好的例子。(例如,您不希望某个Uri被某些不受信任的代码更改。)这意味着您可以传递对不可变对象的引用,而不必担心内容会发生更改


希望这有帮助

一个不可变的对象是你可以放心地认为不会改变的东西;它有一个重要的特性,每个使用它的人都可以假设他们看到了相同的值


不变性通常还意味着您可以将对象视为一个“值”,并且对象的相同副本与对象本身之间没有实际区别。

听着,我还没有阅读您发布的链接

然而,这是我的理解。
每个程序都拥有一些关于其数据(状态)的知识,这些数据可以通过用户输入/外部更改等进行更改

保持变量(变化的值)以保持状态。 不可变意味着某些数据是不变的。您可以说,它在某种程度上与只读或常量相同(可以这样看)

顺便说一句,函数式编程有一些东西是不可变的(也就是说,你不能对一个保存值的变量赋值。你可以做的是创建另一个保存原始值+更改的变量)

.net具有字符串类,这是一个示例。
i、 e.不能在其位置修改字符串

字符串s=“hello”; 我可以写s.Replace(“el”,“a”);但这不会修改变量s的内容

我能做的就是 s=s。替换(“el”、“a”)
这将创建一个新变量并将其值分配给s(覆盖s的内容)

根据我的理解,如果我有错误,专家可以纠正


EDIT:Immutable=一旦它具有某种价值就不可分配&无法替换(可能?)

不变的东西永远不会改变。易变的事物可以改变。易变的事物会发生变异。不变的事物看起来是变化的,但实际上创造了一个新的可变事物

例如,这里有一张Clojure中的地图

(def imap {1 "1" 2 "2"})
(conj imap [3 "3"])
(println imap)
第一行创建一个新的不可变Clojure映射。第二行将3和“3”与地图相连。这可能看起来像是在修改旧地图,但实际上它返回的是添加了3“3”的新地图。这是不变性的一个主要例子。如果这是一个可变的映射,它只需将3“3”直接添加到相同的旧映射中。第三行打印地图

{3 "3", 1 "1", 2 "2"}

不变性有助于保持代码干净和安全。这就是为什么函数式编程语言倾向于不变性和更少的状态性

使事物不变可以避免大量常见错误

例如,一个学生不应该让学生在身上换衣服。如果您没有提供设置变量的方法(并将其设置为const、final或您的语言支持的任何形式),那么您可以在编译时强制执行该方法

如果事情是可变的,当你传递它们时,你不希望它们改变,那么你需要制作一个你传递的防御性副本。然后,如果调用的方法/函数更改了项的副本,则原始项将保持不变

使事物不变意味着你不必记住(或花时间/记忆)来制作防御性拷贝

如果你真的这么做,想想你所做的每一个变量,你会发现你的绝大多数变量(我通常有90-95%)在给定一个值后永远不会改变。这样做可以使程序更容易遵循,并减少bug的数量

要回答关于状态的问题,状态是“对象”(类或结构)的变量所具有的值。如果你把一个人的“对象”状态会像眼睛的颜色,头发的颜色,头发的长度等事情。。。其中一些(比如眼睛的颜色)不会改变,而另一些(比如头发的长度)会改变。

好问题

多线程。如果所有类型都是不可变的,那么竞争条件就不存在,您可以在代码中抛出任意多的线程

显然,如果没有可变性,您就无法完成那么多任务。因此,您通常需要一些可变性来创建功能性业务软件。然而,值得注意的是,不变性应该存在于什么地方,比如任何事务性的东西

查找函数式编程和纯度的概念
String myString = new ImmutableString("hello");
myString.appendString(" world"); // Can't do this
myString.setValue("hello world"); // Can't do this
myString = new ImmutableString("hello world"); // OK
String myString = "HeLLo WoRLd";
String lowercasedString = lowercase(myString);
print myString + " was converted to " + lowercasedString;
string SlowStringAppend(string [] files)
{
    // Declare an string
    string result="";

    for (int i=0;i<files.length;i++)
    {
        // result is a completely new string equal to itself plus the content of the new
        // file
        result = result + File.ReadAllText(files[i]);
    }

    return result;
}    

string EfficientStringAppend(string [] files)
{
    // Stringbuilder manages a internal data buffer that will only be expanded when absolutely necessary
    StringBuilder result=new SringBuilder();

    for (int i=0;i<files.length;i++)
    {
        // The pre-allocated buffer (result) is appended to with the new string 
        // and only expands when necessary.  It doubles in size each expansion
        // so need for allocations become less common as it grows in size. 
        result.Append(File.ReadAllText(files[i]));
    }

    return result.ToString();
}
string mystring = "inital value";
mystring = "new value";
System.Console.WriteLine(mystring); // Outputs "new value";
shared v = Integer(3)
v = Integer(v.value() + 1) # in parallel
Book bookPotter =  new Book();
bookPotter.setAuthor('J.K Rowling');
bookPotter.setTitle('Harry Potter');
Book bookLor =  bookPotter; // only reference pass
bookLor.setAuthor('J.R.R Tolkien');
bookLor.setTitle('Lords of The Rings');
Book bookPotter =  new Book('J.K Rowling', 'Harry Potter');
Book bookLor = new Book('J.R.R Tolkien', 'Lord of The Rings');