对象类型

《...我们是谁?...》——保罗·高更1897

程序设计的实践,不是一个精确定义的领域,我们谈的概念里,有些是约定俗成,有些也有歧义。
因此,本文也有自己约定.

  • "对象",
    说的是一个指称实体,有时它指”符号",有时它指"变量",在这里指内存地址映射的实体,
    var a = "what am I";
    a 是一个变量, 而"what am I"是一个对象。

  • ”作用域"
    有时指的是栈帧(有时引入底层实现导致混淆清晰的语义),这里说的作用域,指一个变量符号的可见范围(和生命周期相关)。

1. ”值"类型,"引用"类型

  • 生命周期管理方式不同,在很多语言里:一个值对象出了作用域即被回收,而一个引用可以被多变量持有,一旦失去所有引用,进入垃圾回收范围;
  • 赋值的语义不同,对于一个变量赋值来说,值类型是拷贝语义,引用类型是全同语义。
    //c#里struct 声明了值对象,class则是引用对象
    struct VAL
    {
    public string a;
    public void print()
    {
    Console.WriteLine("VAL: {0}", a);
    }
    }

    class REF
    {
        public string a;
        public void print()
        {
            Console.WriteLine("REF: {0}", a);
        }
    }
    
    static void Main(string[] args)
    {
        VAL va = new VAL { a = "origin" };
        VAL vb = va;
        va.a = "changed";//修改对象
        va.print();
        vb.print();
    
        REF ra = new REF { a = "origin" };
        REF rb = ra;
        ra.a = "changed";//修改对象
        ra.print();
        rb.print();
    }
    //输出
    VAL: changed
    VAL: origin
    REF: changed
    REF: changed
    //VAL赋值导致了对象拷贝
    

二. 基础类型,复合类型

  • 基础类型就是语言里原生提供的类型,
    比如说通常的 bool, int, string,

  • 复合类型,使得编程语言具有抽象能力,

    • struct 复合(tuple类型/乘法类型)
      struct soldier {int id, string name}

    • enum 复合 (ADT类型/加法类型)
      enum calc { add (int, int), sub (int, int), minus int}

    • list 复合,可用迭代操作的类型
      list

    • map 复合,可被索引类型,
      map

    在编程语言中,以上四种类型并非必需,也不一定是全部,有些语言内置以上所有类型(python),有些语言用库构造复杂类型(java, c++),有些语言只使用其中一种就够了(lua, lisp),

  • 有些语言还允许构造高阶类型——函数类型,

    • c#:
      System.Func //表示一个输入为int, 输出为int的函数复合

    • c++:
      std::function //同上

    • haskell:
      int -> int //同上

    高阶类型的可以用来实现非常强大的抽象——组合子逻辑。(配合语法糖, haskell do notation )

三. 类型的其它修饰符

  • 不变类型(注意并非指 const 变量)

    • 基础类型是不变类型,
      string a = "object in compile time";
      你无法修改 这个字串本身, 变量a替换了指向的对象。

    • 可把基础类型包装成可变类型(装箱)
      class Box
      {
      public T inner
      {
      set;get;
      }
      public override string ToString()
      {
      return inner.ToString();
      }
      }

          static void Main(string[] args)
          {
              int a = 1;
              int b = a;
              a = 2;
              Console.WriteLine("a:{0} b:{1}", a, b);
      
              var ao = new Box { inner = 1 };
              var bo = ao;
              ao.inner = 2;
              Console.WriteLine("ao:{0} bo:{1}", ao, bo);
          }
          //输出
          > a:2 b:1
          > ao:2 bo:2
      
    • 可以对复合类型field 声明不变属性(scala)

    • 内部可变性

  • lazy/promise
    表示一种对象求值策略,当一个对象被需要,才生成/被求值(option, 并被保存),这是一种常用的设计模式,
    我也许在下篇文章里谈谈(lazy模式)

  • 子类型
    通过声明继承,实现类型系统结构化,理想化的类型结构是格子
    使得调用接口能够协变,逆变,增加库的通用能力;

这里讲了类型不同维度的定义,思考题
//1. 你认为,java 里的基础类型,是值类型还是引用类型(参考可变性)
//2. 有人说,java, c#里可以用继承,实现 enum类型, 你认为这种说法对吗?

    //定义
    class Color;
    class Red : color;
    class Blue : color;
    
    //分派:
    if( red is Color)
        ...
    else if(blue is Color)
            ...
    //////////////////ADT
    //定义
    type color = red | blue;
    
    //分派
    case col of:
        red => ...
        blue => ...
  //你能举出它们的至少一处区别吗?

你可能感兴趣的:(对象类型)