【问题标题】:How to fully dump / print variable to console in the Dart language?如何以 Dart 语言将变量完全转储/打印到控制台?
【发布时间】:2017-07-15 08:51:59
【问题描述】:

嘿,我正在寻找一个函数,它以 Dart 语言将动态变量尽可能完整地打印到控制台。

例如,在 PHP 中,我会使用 var_dump() 来获取有关变量的所有信息。

JavaScript 中,我会执行以下操作之一:

1) 将 Object 转换为 JSON 并打印 console.log(JSON.stringify(obj))

2) 或者像这样的自定义函数:

 function dump(arr,level) {
  var dumped_text = "";
  if(!level) level = 0;

  //The padding given at the beginning of the line.
  var level_padding = "";
  for(var j=0;j<level+1;j++) level_padding += "    ";

  if(typeof(arr) == 'object') { //Array/Hashes/Objects 
   for(var item in arr) {
    var value = arr[item];

    if(typeof(value) == 'object') { //If it is an array,
     dumped_text += level_padding + "'" + item + "' ...\n";
     dumped_text += dump(value,level+1);
    } else {
     dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
    }
   }
  } else { //Stings/Chars/Numbers etc.
   dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
  }
  return dumped_text;
 }

但是在 Dart 中,如果我执行print(variable),我会得到类似Instance of 'FooBarObject' 的信息。我不能像在 JavaScript 中那样将对象转换为 JSON,因为这对所有对象都是不可能的。

所以我的问题详细:

dart 中的函数或自定义函数在哪里可以打印未知类型(对象、数组等)的变量,包括所有(公共)属性以及嵌套对象和变量到我的控制台?或者哪个功能最接近这个愿望?

【问题讨论】:

    标签: debugging dart


    【解决方案1】:

    dart:developer library 包括inspect function,它允许调试器在对象上打开检查器。

    要使用它,请添加:

    import 'dart:developer';
    

    然后你可以在控制台中看到你检查的变量/对象:

    inspect(myVar);
    

    【讨论】:

    • 这个超级好用!
    • 这应该是公认的答案,因为它比实现自己的 toString() 容易得多
    【解决方案2】:

    如果是地图,则可以转换为JSON。首先从flutter导入convert包。

    import 'dart:convert';
    

    然后转换为JSON 并打印

    print(json.encode(yourMapVariable));
    

    更新

    以上答案适用于地图。对于 class / object 添加到 toString() 方法。

    例如:假设我们有一个user class

    class User {
      String name;
      String address;
    
      toString() {
        return "name: " + name + ", address: " + address;
      }
    }
    

    您可以使用您的IDE 自动生成此toString() 方法。

    【讨论】:

    • 错误Uncaught Error: Converting object to an encodable object failed: Instance of 'User'
    • @Aravin 你弄错了,你正在尝试打印一个对象。上面的答案是map。如果您有用户class,更好的方法是向其添加toString() 方法。
    【解决方案3】:

    简单的小技巧就可以完成这项工作

    void printObject(Object object) {
      // Encode your object and then decode your object to Map variable
      Map jsonMapped = json.decode(json.encode(object)); 
    
      // Using JsonEncoder for spacing
      JsonEncoder encoder = new JsonEncoder.withIndent('  '); 
    
      // encode it to string
      String prettyPrint = encoder.convert(jsonMapped); 
    
      // print or debugPrint your object
      debugPrint(prettyPrint); 
    }
    
    // To use simply pass your object to it
    printObject(yourObject); 
    

    【讨论】:

    • 解释你的代码会提高你帖子的质量。
    • 哇,太有用了。我稍微调整了一下,但那个编码器正是我想要的!终于可以轻松阅读日志了!
    【解决方案4】:

    如果您想了解更多关于 android studio 中任何类的实例的信息,请单击变量前的类名,然后按 ctrl+b,它将带您进入该对象所属的类文件,您可以从那里看到用户属性和这个类的方法。

    【讨论】:

      【解决方案5】:

      在异步函数中对对象使用 await 关键字 void _registerUser() async { print(await form.result); }

      【讨论】:

        【解决方案6】:

        Instance of 'FooBarObject' 当您尝试直接执行 print(object); 时会发生这种情况

        即使你使用来自flutter的convert包,它也会抛出Uncaught Error: Converting object to an encodable object failed:

        要解决此问题,首先,请确保您的模型类或数据类包含 fromJsontoJson 方法。

        如果这样做,您的模型类将如下所示。

        class User {
          String name;
          String gender;
          int age;
        
          User({this.name, this.gender, this.age});
        
          User.fromJson(Map<String, dynamic> json) {
            name = json['name'];
            gender = json['gender'];
            age = json['age'];
          }
        
          Map<String, dynamic> toJson() {
            final Map<String, dynamic> data = new Map<String, dynamic>();
            data['name'] = this.name;
            data['gender'] = this.gender;
            data['age'] = this.age;
            return data;
          }
        }
        

        并将其打印为json import convert package

        import 'dart:convert';
        

        并致电json.encode

        //after initializing the user object
         print('value is--> ' + json.encode(user);
        

        将数据打印为

        value is--> {"name": "Vignesh","gender": "Male","age": 25}
        

        【讨论】:

          【解决方案7】:

          试试这个..

            void printWrapped(String text) {
              final pattern = new RegExp('.{1,800}'); // 800 is the size of each chunk
              pattern.allMatches(text).forEach((match) => print(match.group(0)));
            }
          

          【讨论】:

          • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助、质量更好,并且更有可能吸引投票。
          【解决方案8】:

          没有生成这样的输出的内置函数。

          print(variable) 打印 variable.toString()Instance of 'FooBarObject' 是默认实现。您可以在自定义类中覆盖它并打印不同的内容。

          您可以使用反射 (https://www.dartlang.org/articles/libraries/reflection-with-mirrors) 自己构建一个函数,以调查实例的各种属性并以您想要的方式打印它。 您可以做什么几乎没有限制,出于调试目的,它绝对是一个不错的选择。

          对于生产 Web 应用程序,应该避免它,因为它严重限制了 tree-shaking 并且会导致构建输出大小显着增加。 Flutter (mobile) 根本不支持反射。

          您还可以使用其中一种 JSON 序列化包,它可以轻松地将序列化添加到自定义类,然后打印序列化值。 例如

          我认为还有其他的,但我不知道(不利)优势,因为我通常使用https://pub.dartlang.org/packages/source_gen 自己推出自己的产品

          【讨论】:

          • DSON 包对我来说非常好,如果我尝试使用反射的自定义解决方案,我会在这里发布,谢谢。
          • 有很多关于反射的问题的答案。他们中的大多数应该仍然可以工作。反射并没有太大变化。如果您想在 Web 应用程序的生产环境中使用反射,还有 reflectable 包,可以将反射代码转换为静态代码,以免影响 tree-shaking。
          猜你喜欢
          • 2018-05-12
          • 1970-01-01
          • 1970-01-01
          • 2014-01-28
          • 2010-10-22
          • 2016-05-01
          • 2018-12-15
          • 2018-11-24
          • 2021-06-27
          相关资源
          最近更新 更多