结论:两种方式拿到的是同一个字典,不是两份。「创建字典」放进去的是这个字典本身(引用),不会复制一份。所以:• 通过大字典改了它的内容,直接读变量也能看到,反过来也一样;• 但如果之后给变量重新赋值一个新字典,大字典里存的还是原来那个,两边就分开了;• 效率上几乎没有差别,差的只是多查一次键,微秒级。下面用三个小实验看清楚。界面只需要一个标签 Label1 和三个按钮 Button1~Button3。实验一:从大字典里改,变量里也变了屏幕初始化时,先给小字典赋值,再把它放进大字典。点按钮时,通过大字典把滴速改成 9,然后直接读变量:
跑起来看:点 Button1,标签显示 直接读变量:9。改的是大字典里 key1 的值,变量也跟着变了,说明它们是同一个字典。可以理解成:变量和大字典的 key1 是贴在同一个盒子上的两张标签,从哪张标签找过去,打开的都是同一个盒子。
实验二:给变量重新赋值,两边就分开了还是一样的初始化。这次点按钮时,给变量重新赋值一个新字典,再分别读:
跑起来看:点 Button2,标签显示 直接读变量:7,经大字典读:6。「设置 全局变量 为 创建字典」是把变量这张标签撕下来,贴到一个新盒子上;大字典的 key1 还贴在旧盒子上,不会自动跟过去。
这是最容易踩的坑:一处改了「整个换掉」,另一处还在用旧数据,程序不报错,只是结果不对。规则很简单:• **改内容**(「设置 键 在字典 值为」「删除键的条目」这类块):两边同步;• **重新赋值**(设置 全局变量 为 一个新字典):两边分家。想让大字典也用新的,要再执行一次「设置 键 key1 在字典 参数大字典 值为 新字典」。实验三:想要互不影响,就复制一份如果你希望大字典里存的是「出厂默认值」,之后怎么改变量都不影响它,就用字典抽屉的「复制字典」先复制一份再放进去:
跑起来看:点 Button3,标签显示 直接读变量:6。大字典里改成了 9,变量不受影响。注意「复制字典」是浅复制:只复制最外面一层。如果小字典里面还嵌着字典或列表,里面那些仍然是同一个,改深层的内容两边还会一起变。效率:几乎没区别• 直接读变量:取一次变量;• 经大字典读:取一次变量,再按键查一次。字典按键查找不用逐个比较,很快。多出来的这一步是微秒级的,点按钮、处理一条蓝牙数据这种频率完全感觉不到。只有在几千次的循环里反复「从大字典取 key1」,才值得在循环外先取出来存进局部变量,循环里直接用。推荐写法两种访问方式都能用,关键是别让同一份数据有两个「主人」:做法 适合 注意只保留大字典,用时按键取 参数组多、要整体保存或发送 写一个「取工作模式参数」过程,取值的地方都调它,键名只写一处只用小字典变量,需要时再临时组装大字典 各组参数分开改、很少整体用 组装放在要用的那一刻(比如保存、发送前),保证拿到最新值两边都留 不推荐 只能改内容、不能重新赋值,否则就是实验二的坑另外,用微数据库保存再读回来时,大字典和变量各自读出来的是两个独立的新字典(保存时变成了文本),原来的「同一个盒子」关系就没有了。读回后如果还想两边连着,要重新组装一次大字典。结论直接用变量和通过大字典取,拿到的是同一个字典,效率也几乎一样。真正要注意的是「重新赋值会分家」:改内容两边同步,整个换掉就不同步了。想要独立的一份,用「复制字典」。安卓和鸿蒙行为一致,文中三个实验的结果都在运行时里实际跑过。完整文档见 App Inventor 2 中文网「技巧分享」栏目。
| 欢迎光临 AppInventor2 中文社区 (https://bbs.tsingfun.com/) | Powered by Discuz! X3.3 |