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

   2023-02-09 学习力0
核心提示:其实定长List和可增长List的对象的runtimeType是不一样的(泛型类型一样),但是它们的toString是一致的(hashCode不一样),这个不清楚是运行时做了特殊化处理,还是在代码层面做的处理;这里做一些比较,以及最后实现两种List的runtimeType;【注意在运行时

其实定长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() + ">";
  }
}
 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • Dart空安全的底层原理与适配
    Dart空安全的底层原理与适配
    一、在空安全推出之前,静态类型系统允许所有类型的表达式中的每一处都可以有 null。从类型理论的角度来说,Null 类型被看作是所有类型的子类;   类型会定义一些操作对象,包括 getters、setters、方法和操作符,在表达式中使用。如果是 List 类型,您可
    03-08
  • Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    Flutter开发指南之理论篇:Dart语法05(单线程
    此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate) Flutter开发指南之理论篇:Flutter基础01(架构,设计思想) Dart是一门面向对象语言,它针对web 和移
    03-08
  • Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    Flutter开发指南之理论篇:Dart语法05(单线程
    此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate) Flutter开发指南之理论篇:Flutter基础01(架构,设计思想) Dart是一门面向对象语言,它针对web 和移
    03-08
  • Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    Flutter开发指南之理论篇:Dart语法05(单线程
    此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate) Flutter开发指南之理论篇:Flutter基础01(架构,设计思想) Dart是一门面向对象语言,它针对web 和移
    03-08
  • oogle的“ JavaScript杀手” Dart 与JavaScript的比较
    oogle的“ JavaScript杀手” Dart 与JavaScript
    JavaScript通常被称为浏览器脚本语言,但它也已扩展到许多服务器端和移动应用程序开发环境。JS已经存在了将近20年,可以肯定地说它确实是一种成熟且稳定的编程语言。在Facebook发布React和React Native框架之后,JS变得越来越流行。JavaScript具有自己的软件
    03-08
  • Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    Flutter开发指南之理论篇:Dart语法05(单线程
    此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate) Flutter开发指南之理论篇:Flutter基础01(架构,设计思想) Dart是一门面向对象语言,它针对web 和移
    03-08
  • Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    Flutter开发指南之理论篇:Dart语法05(单线程
    此文转载自:https://blog.csdn.net/AndrExpert/article/details/110823218Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate) Flutter开发指南之理论篇:Flutter基础01(架构,设计思想) Dart是一门面向对象语言,它针对web 和移
    03-08
  • flutter 填坑之旅(dart学习笔记篇)
    flutter 填坑之旅(dart学习笔记篇)
    俗话说 ‘工欲善其事必先利其器’ 想要撸flutter app 而不懂 dart 那就像一个不会英语的人在和英国人交流,懵!安装 dart 就不用说了,比较简单dart 官网 https://dart.dev/安装完成后就开启学习dart 旅程吧…一、 首先得找个ide (总不能使用记事本撸吧),所
    03-08
  • dart 命令行
       dart build 
    02-09
  • dart系列之:dart语言中的异常 dart新手的错误
    目录简介Exception和ErrorThrow和catchFinally总结简介Exception是程序中的异常情况,在JAVA中exception有checked Exception和unchecked Exception。那么在dart中的情况是不是一样的呢?一起来看看吧。Exception和ErrorDart中表示异常的类有两个,分别是Excep
    02-09
点击排行