zoukankan      html  css  js  c++  java
  • 论immutable不可变性

    什么叫immutable和mutable?简单来讲,一个immutable的对象一旦被创建好,它的状态将不会改变。反过来,如果一个类的实例是immutable的,那么我们把这个类也称作immutable class。

    immutable的优势

    • 便于多线程编程
    • 方便地作为hashtable的key
    • 便于比较状态

    说明:本身变化才叫变化,类似string,int(等基元值类型)默认已经是不可变的,如果你修改他们,只是重新分配一个新的而矣。如果是自定义的值类型struct,最好也指定为immutable。

    通过readonly来指定。

    C#中immutable的实现

    经典的immutable class

    class Contact
    {
        public Contact(String fullName, String phoneNumber)
        {
            this.fullName= fullName;
            this.phoneNumber= phoneNumber;
        }

        public Contact ChangeNumber(String newNumber)
        {
            //创建一个新实例
            return new Contact (this.fullName, newNumber);
        }

        readonly String fullName;
        public String FullName get return fullName; }}

        readonly String phoneNumber;
        public uint PhoneNumberget return phoneNumber; }}
    }

    这个例子几乎无须再解释,每次changeNumber的时候就构造一个新的Contact对象。

    C# 对immutability的支持离不开这两个关键字: constreadonly。C#的编译器使用这两个关键字来确保某创建好的对象的状态不会发生改变。之所以提供这两个关键字,自然是因为它们还是有所区别的。readonly允许在构造器中改变它的状态(初始化),而const则不行。例如:

     

    class cnblogs{
       Article(string author,string title) 

          a_title= title; 
          authorName = author; // 编译此处会报错
       }

       readonly string a_title;
       const string authorName "Freesc";
    }

    (其他关于readonly和const的讨论,见这里

     

    现在也许你会问,如果我的对象通过一个readonly的字段引用了另一个对象会怎样呢?引用的对象的状态会发生改变么?答案是肯定的,看下面的例子:

    public class C 

        private static readonly int[] ints new int[] 123 };
        public static int[] Ints get return ints; }

     }

    这里如果我们尝试在C中改变数组的值:C.ints = null;是无效的操作,这就是一种所谓的“引用不可变”,注意这里只是说引用不可变,如果你尝试在C外部使用:C.Ints[1] = 123;这样的操作,你会发现数组本身其实是可以改变的。我们姑且可以把ints字段称之为“浅”不可变字段。所以你可以相对灵活的指定你需要immutable的字段,可以参考Eric Lippert的文章.

    与hashtable的相关性,只有immutable的对象作为hash的键,才能保证hash值始终为常量。当然,通常hash的值是从对象的某些状态(或者子状态)计算而来,而对象的这些状态(子状态)应为immutable。

    以下摘取,可以释疑

    In Java strings are immutable. If we have a string and make changes to it, we get new string referenced by the same variable:

    String str = "abc";
    str += "def"; // now str refers to another piece in the heap containing "abcdef"
                  // while "abc" is still somewhere in the heap until taken by GC
    

    It's been said that int and double are immutable in C#. Does it mean that when we have int and later change it, we would get new int "pointed" by the same variable? Same thing but with stack.

    int i = 1;
    i += 1; // same thing: in the stack there is value 2 to which variable
            // i is attached, and somewhere in the stack there is value 1
    

    Is that correct? If not, in what way is int immutable?

    You haven't changed (and cannot change) something about the int; you have assigned a new int value (and discarded the old value). Thus it is immutable.

    Consider a more complex struct:

    var x = new FooStruct(123);
    x.Value = 456; // mutate
    x.SomeMethodThatChangedInternalState(); // mutate
    
    x = new FooStruct(456); // **not** a mutate; this is a *reassignment*
    

    However, there is no "pointing" here. The struct is directly on the stack (in this case): no references involved.

  • 相关阅读:
    阿里DatatX mysql8往 Elasticsearch 7 插入时间数据 时区引发的问题
    通俗易懂 k8s (3):kubernetes 服务的注册与发现
    ReplicaSet 和 ReplicationController 的区别
    使用Go module导入本地包
    k8s之statefulset控制器
    终于成功部署 Kubernetes HPA 基于 QPS 进行自动伸缩
    Atitit drmmr outline org stat vb u33.docx Atitit drmmr outline org stat v0 taf.docx Atitit drmmr out
    Atitit all diary index va u33 #alldiary.docx Atitit alldiaryindex v1 t717 目录 1. Fix 1 2. Diary deta
    Atitit path query 路径查询语言 数据检索语言 目录 1.1. List map >> spel 1 1.2. Html数据 》》Css选择符 1 1.3. Json 》map》
    Atitit prgrmlan topic--express lan QL query lan表达式语言 目录 1. 通用表达语言(CEL) 1 1.1. 8.2 功能概述 1 1.2. Ongl
  • 原文地址:https://www.cnblogs.com/qook/p/5421406.html
Copyright © 2011-2022 走看看