• Dart里实现可增长List和定长List的runtimeType的toString()的值是一样的功能


    其实定长List和可增长List的对象的runtimeType是不一样的(泛型类型一样),但是它们的toString是一致的(hashCode不一样),这个不清楚是运行时做了特殊化处理,还是在代码层面做的处理;

    这里做一些比较,以及最后实现两种List的runtimeType;

    【注意在运行时里_List<int>和_List<int?>的runtimeType是不同的,因此是否可空是保存在了内存里而没有在运行时擦除,因此原理上是可以做反射的】

    import 'dart:mirrors';
    import 'rr.dart' as t;
    
    void main(List<String> arguments) {
      var ss = List<int>.filled(1, 0);
      print(ss.runtimeType.runtimeType);
      print(ss.runtimeType.toString());
      print(ss.runtimeType.hashCode);
      var okk1 = reflect(ss.runtimeType);
      print(okk1);
      
      var kk = List.filled(4, 4);
      print(okk1 == reflect(kk.runtimeType));
      print(kk.runtimeType.hashCode);
      print('Hello world!');
      print(reflect(ss).type);
      var uu = List<int>.filled(3, 0, growable: true);
      var st = List<int>.filled(8, 9, growable: true);
      print(reflect(uu).type);
      var okk2 = reflect(uu.runtimeType);
      print(okk2);
      print(okk1 == okk2);
      
      print(uu.runtimeType);
      print(uu.runtimeType.hashCode);
      print(st.runtimeType.hashCode);
      test(4);
      // 证明runtimeType确实可以作为区分类型的key
      // 只是runtimeType.toString()是可能多个类型的输出值是一样的
      // 即_List和_GrowableList都对toString方法进行了重载,然后
      // 都输出的List<..>【当然,这个貌似是编译器内部的一种重载,程序员无法
      // 实现】【不过也可以自己实现,即覆盖runtimeType这个计算属性】
      // 这个自己写代码也是会遇到的,比如两个类型在不同模块里
      // ,但是都叫Uuu,因此他们对象的runtimeType的toString()值是一致的,
      // 但是他们不相等;
    
      print(ss.runtimeType == uu.runtimeType);
      print(ss.runtimeType == kk.runtimeType);
      print(uu.runtimeType == st.runtimeType);
      print(st.runtimeType == ss.runtimeType);
      var uus = List<double>.filled(3, 8, growable: true);
      print(uus.runtimeType == uu.runtimeType);
      print("------------");
      Umm sss = Umm();
      print(sss.runtimeType);
      print(sss.runtimeType.hashCode);
      Umm sst = Umm<int>();
      print(sst.runtimeType == sss.runtimeType);
      print(sst.runtimeType.hashCode);
      Umm ssss = Umm(s: 4);
      print(ssss.runtimeType == sss.runtimeType);
      print(ssss.runtimeType.hashCode);
      print(reflect(ssss.runtimeType));
      Ukk rrr = Ukk();
      print(rrr.runtimeType);
      print(rrr.runtimeType.hashCode);
      Ukk rrt = Ukk<int>();
      print(rrt.runtimeType);
      print(rrt.runtimeType == rrr.runtimeType);
      print(rrr.runtimeType == sss.runtimeType);
      print(rrr.runtimeType);
      print(sss.runtimeType);
      print(rrr.runtimeType.runtimeType);
      print(sss.runtimeType.runtimeType);
      print(sss.runtimeType.runtimeType.runtimeType);
      print(rrt.runtimeType.hashCode);
      Ukk rrrr = Ukk(s: 4);
      print(rrrr.runtimeType == rrr.runtimeType);
      print(rrrr.runtimeType.hashCode);
      print(reflect(rrrr.runtimeType));
    }
    
    void test([int? ss=null]) {
      print(ss);
    }
    
    class Umm<T> {  // 模拟_GrowableList
      Type get runtimeType => UmmType.tType<T>();
      int? s;
      Umm({int? s}) {
        this.s = s;
      }
    }
    
    class UmmType<T> extends Type {
    
      static Map<Type, Type> types = Map();
    
      // M也是Type的一种,注意Type和Class又是不同的
      // 比如extension是Type却不是Class
      // 所有的对象都是Object的子类,而不是所有的类型都是Object的子类
      static Type tType<M>() {
        // 防并发没有,需要补上
        if (types.containsKey(M)) {
          return types[M]!;
        } else {
          types[M] = UmmType<M>();
          return types[M]!;
        }
      }
    
      @override
      String toString() {
        // T 在这里是T实际类型对象的runtimeType值
        return "Lost<" + T.toString() + ">";
      }
    }
    
    class Ukk<T> {  // 模拟_List
      // 只要两个Type的定义是在不同的文件里,则是可以同名的
      // 同名不代表同类型;
      Type get runtimeType => t.UmmType.tType<T>();
      int? s;
      Ukk({int? s}) {
        this.s = s;
      }
    }
    
    class UkkType<T> extends Type {
    
      static Map<Type, Type> types = Map();
    
      // M也是Type的一种,注意Type和Class又是不同的
      // 比如extension是Type却不是Class
      // 所有的对象都是Object的子类,而不是所有的类型都是Object的子类
      static Type tType<M>() {
        // 防并发没有,需要补上
        if (types.containsKey(M)) {
          return types[M]!;
        } else {
          types[M] = UkkType<M>();
          return types[M]!;
        }
      }
    
      @override
      String toString() {
        return "Lost<" + T.toString() + ">";
      }
    }
    import 'dart:mirrors';
    import 'rr.dart' as t;

    void main(List<String> arguments) {
      var ss = List<int>.filled(10);
      print(ss.runtimeType.runtimeType);
      print(ss.runtimeType.toString());
      print(ss.runtimeType.hashCode);
      var okk1 = reflect(ss.runtimeType);
      print(okk1);
      
      var kk = List.filled(44);
      print(okk1 == reflect(kk.runtimeType));
      print(kk.runtimeType.hashCode);
      print('Hello world!');
      print(reflect(ss).type);
      var uu = List<int>.filled(30, growable: true);
      var st = List<int>.filled(89, growable: true);
      print(reflect(uu).type);
      var okk2 = reflect(uu.runtimeType);
      print(okk2);
      print(okk1 == okk2);
      
      print(uu.runtimeType);
      print(uu.runtimeType.hashCode);
      print(st.runtimeType.hashCode);
      test(4);
      // 证明runtimeType确实可以作为区分类型的key
      // 只是runtimeType.toString()是可能多个类型的输出值是一样的
      // 即_List和_GrowableList都对toString方法进行了重载,然后
      // 都输出的List<..>【当然,这个貌似是编译器内部的一种重载,程序员无法
      // 实现】【不过也可以自己实现,即覆盖runtimeType这个计算属性】
      // 这个自己写代码也是会遇到的,比如两个类型在不同模块里
      // ,但是都叫Uuu,因此他们对象的runtimeType的toString()值是一致的,
      // 但是他们不相等;

      print(ss.runtimeType == uu.runtimeType);
      print(ss.runtimeType == kk.runtimeType);
      print(uu.runtimeType == st.runtimeType);
      print(st.runtimeType == ss.runtimeType);
      var uus = List<double>.filled(38, growable: true);
      print(uus.runtimeType == uu.runtimeType);
      print("------------");
      Umm sss = Umm();
      print(sss.runtimeType);
      print(sss.runtimeType.hashCode);
      Umm sst = Umm<int>();
      print(sst.runtimeType == sss.runtimeType);
      print(sst.runtimeType.hashCode);
      Umm ssss = Umm(s: 4);
      print(ssss.runtimeType == sss.runtimeType);
      print(ssss.runtimeType.hashCode);
      print(reflect(ssss.runtimeType));
      Ukk rrr = Ukk();
      print(rrr.runtimeType);
      print(rrr.runtimeType.hashCode);
      Ukk rrt = Ukk<int>();
      print(rrt.runtimeType);
      print(rrt.runtimeType == rrr.runtimeType);
      print(rrr.runtimeType == sss.runtimeType);
      print(rrr.runtimeType);
      print(sss.runtimeType);
      print(rrr.runtimeType.runtimeType);
      print(sss.runtimeType.runtimeType);
      print(sss.runtimeType.runtimeType.runtimeType);
      print(rrt.runtimeType.hashCode);
      Ukk rrrr = Ukk(s: 4);
      print(rrrr.runtimeType == rrr.runtimeType);
      print(rrrr.runtimeType.hashCode);
      print(reflect(rrrr.runtimeType));
    }

    void test([int? ss=null]) {
      print(ss);
    }

    class Umm<T> {  // 模拟_GrowableList
      Type get runtimeType => UmmType.tType<T>();
      int? s;
      Umm({int? s}) {
        this.s = s;
      }
    }

    class UmmType<Textends Type {

      static Map<TypeType> types = Map();

      // M也是Type的一种,注意Type和Class又是不同的
      // 比如extension是Type却不是Class
      // 所有的对象都是Object的子类,而不是所有的类型都是Object的子类
      static Type tType<M>() {
        // 防并发没有,需要补上
        if (types.containsKey(M)) {
          return types[M]!;
        } else {
          types[M] = UmmType<M>();
          return types[M]!;
        }
      }

      @override
      String toString() {
        // T 在这里是T实际类型对象的runtimeType值
        return "Lost<" + T.toString() + ">";
      }
    }

    class Ukk<T> {  // 模拟_List
      // 只要两个Type的定义是在不同的文件里,则是可以同名的
      // 同名不代表同类型;
      Type get runtimeType => t.UmmType.tType<T>();
      int? s;
      Ukk({int? s}) {
        this.s = s;
      }
    }

    class UkkType<Textends Type {

      static Map<TypeType> types = Map();

      // M也是Type的一种,注意Type和Class又是不同的
      // 比如extension是Type却不是Class
      // 所有的对象都是Object的子类,而不是所有的类型都是Object的子类
      static Type tType<M>() {
        // 防并发没有,需要补上
        if (types.containsKey(M)) {
          return types[M]!;
        } else {
          types[M] = UkkType<M>();
          return types[M]!;
        }
      }

      @override
      String toString() {
        return "Lost<" + T.toString() + ">";
      }
    }
  • 相关阅读:
    网站、数据库的衍变之路(三)
    脚本嵌入式抓取引擎
    db4objects 7.4应用笔记
    网站、数据库的衍变之路(二)
    IIS连接数实验——Web开发必读
    攻破WebService,WCF的改进
    C#使用BerkeleyDB操作简介
    面试两个星期来的一点体会
    Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)
    轻量级爬虫+全文检索解决方案项目——NukeLite(20081114 更新r24版 引入新线程机制)
  • 原文地址:https://www.cnblogs.com/silentdoer/p/14484768.html
Copyright © 2020-2023  润新知