为什么使用List <dynamic>而不使用List <map <string,dynamic >>?

时间:2019-04-08 15:52:06

标签: json types dart

我有一个小程序,可以使用这种结构来处理一些JSON数据:

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Users</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" />
<link href="~/Content/themes/base/jquery-ui.min.css" rel="stylesheet" />
</head>
<body>
<div style="width:90%; margin:0 auto" class="tablecontainer">
    <a class="popup btn btn-primary" href="/home/CreateUser/0" style="margin-bottom:20px; margin-top:20px">Add new User</a>
    <a class="popup btn btn-primary" href="/home/AddUserToSafe/0" style="margin-bottom:20px; margin-top:20px">Add User to Safe</a>
    <table id="CBR-User">
        <thead>
            <tr>
                <th>User ID</th>
                <th>Name</th>
                <th>Surname</th>
                <th>Department ID</th>
                <th>Rank</th>
                <th>Assigned Safes</th>
                <th>Email Address</th>
                <th>Password</th>
                <th>Add User to Safe</th>
                <th>Edit</th>
                <th>Delete</th>
            </tr>
        </thead>
    </table>
</div>

<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="https://cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js"></script>
<script src="~/Scripts/jquery-ui-1.12.1.min.js"></script>

<script>
    $(document).ready(function () {
        var uTable = $('#CBR-User').DataTable({
            "ajax": {
                "url": '/Home/GetUser',
                "type": "get",
                "datatype": "json"
            },
            "columns": [

                { "data": "User_ID", "autoWidth": true },
                { "data": "FName", "autoWidth": true },
                { "data": "SName", "autoWidth": true },
                { "data": "Department_ID", "autoWidth": true },
                { "data": "Rank", "autoWidth": true },
                { "data": "Safe_ID", "autoWidth": true },
                { "data": "Email_Address", "autoWidth": true },
                { "data": "Password", "autoWidth": true },
                {
                    "data": "User_ID", "width": "50px", "render": function (data) {
                        return '<a class="popup" href="/home/SaveUser/' + data + '">Edit</a>';
                    }
                },
                {
                    "data": "User_ID", "width": "50px", "render": function (data) {
                        return '<a class="popup" href="/home/DeleteUser/' + data + '">Delete</a>';
                    }
                }
            ]
        })

如果我使用动态类型或 var 关键字进行编码,那么一切都会很好,但是在声明类型时出现以下错误。

{ "categories": [{ "id": 0, "title": "cat1" }], "drinks": [{ "categoryId": 0, "image": "image", "title": "title", "text": "text" }] }

这是程序:

'List<dynamic>' is not a subtype of type 'List<Map<String, dynamic>>'

为什么我会收到此错误? import 'dart:convert'; main(List<String> args) { String source = ''' { "categories": [{ "id": 0, "title": "cat1" }], "drinks": [{ "categoryId": 0, "image": "image", "title": "title", "text": "text" }] }'''; var json = jsonDecode(source); // Dynamic types, works ok! var categories = json['categories']; var title = categories[0]['title']; var id = categories[0]['id']; print('$title with $id'); // Explicit types, error! List<Map<String,dynamic>> categories2 = json['categories']; String title2 = categories2[0]['title']; int id2 = categories2[0]['id']; print('$title2 with $id2'); } categories类型的,但是为什么它不是List<dynamic>

1 个答案:

答案 0 :(得分:2)

在Dart中,创建列表时会提供列表的元素类型,并将其保留为列表值的一部分。将元素添加到列表的每种类型,都将检查该元素是否属于该类型。这与Java不同,在Java中,泛型类型参数会在运行时删除。

这意味着Dart List<dynamic>List<Map<String, dynamic>>是不同的,即使两个列表仅包含Map<String, dynamic>>的实例。例如,您可以向前者添加一个整数,而不能向后者添加一个整数。

JSON列表可以包含任何JSON值。 在这种情况下,您的列表仅包含作为映射的值,但这可能是巧合。 JSON解析器不首先检查源代码以查看列表是否仅包含一种对象,而是仅创建一个List<dynamic>并将元素放入其中。创建的列表是可变的,因此有人可能会在返回列表后向该列表添加一个整数。如果解析器将列表改为List<Map<String, dynamic>>,则该代码将中断。

因此,您的列表是List<dynamic>,因为jsonParse创建的所有JSON列表都是...,而将其变为任何其他内容将是一项重大突破。