Dart 如何干净地共享expado或weakmap属性(或其他选项,如果可用)

Dart 如何干净地共享expado或weakmap属性(或其他选项,如果可用),dart,Dart,编辑成原始帖子是不可能理解的…对不起,伙计们 我为什么要使用expando/weakmap? 我有一个自定义的布局/大小调整元素,可以调整子元素的大小。通过使用expando,我希望在不创建强引用的情况下控制调整大小的行为。 e、 g 我找到了一个更好的解决方案,但我想知道如何在Dart中使用数据映射对象,并在多个对象之间安全、动态地共享数据 为什么我想分享expando的房产? 我的布局元素可能包含另一个布局元素并形成树。允许在树的任何位置访问对象的expando属性似乎是一件理性的事情。 e

编辑成原始帖子是不可能理解的…对不起,伙计们

我为什么要使用expando/weakmap? 我有一个自定义的布局/大小调整元素,可以调整子元素的大小。通过使用expando,我希望在不创建强引用的情况下控制调整大小的行为。
e、 g

我找到了一个更好的解决方案,但我想知道如何在Dart中使用数据映射对象,并在多个对象之间安全、动态地共享数据

为什么我想分享expando的房产? 我的布局元素可能包含另一个布局元素并形成树。允许在树的任何位置访问对象的expando属性似乎是一件理性的事情。
e、 g

有什么问题? 无法合并或拆分expando实例。

潜在解决方案 放弃expando属性/weakmap(仅适用于dom元素) 新的HtmleElement()…数据集['allow_layout_resize_this']='false'

没有想到这一点,而是最简单的

反射 很明显,但目前需要“dart:mirror”来处理任何类实例

穿过树 复杂而丑陋

class Layout extends HtmlElement{
  Expando<bool> _freeze_resizing = new Expando<bool>();
  Layout.created():super.created();
  void add_resizable_attribute(HtmlElement e, bool isResizable) {
   _freeze_resizing[e] = !isResizable;
  }

  isFrozen(HtmlElement e,
     {bool search_down: true,
     bool search_up: true
     }) {
   ///resize allowed by default
   bool v;
   if (search_up) {
     Layout t = _get_topmost_layout();
     return t.isFrozen(
         e, search_down: true,
         search_up: false);
   } else if (search_down) {
     v = _freeze_resizing[e];
     v = v == null ? false : v;
     if (v) return true;
     return isFrozen_in_children(e);
   }
   return _freeze_resizing[e];
  }

  bool isFrozen_in_children(e) {
   for (var c in children) {
     if (c is! Layout) continue;
     if (c.isFrozen(
         e,
         search_up: false,
         search_down: true
     )) return true;
   }
   return false;
  }

  Layout _get_topmost_layout() {
   Layout tm;
   var e = this;
   while (e is Layout) {
     tm = e;
     e = e.parent;
   }
   return tm;
  }
  void _enforce_owner_exclusive_expando(element,[bool search_up=true]){
    ///remove expando properties from non-owner
    if(!children.contains(element)){
      _freeze_resizing[element]=null;
    }
    void enforce_on_children(){
      for(var c in children){
        if(c is! Layout) continue;
         c._enforce_owner_exclusive_expando(element,false);
      }
    }
    if(search_up){
      var tm = _get_topmost_layout();
      tm._enforce_owner_exclusive_expando(element,false);
    }else{
      enforce_on_children();
    }
  }
  append(e){
    super.append(e);
    _enforce_owner_exclusive_expando(element);
  }
}
类布局扩展了HtmleElement{
Expando_freeze_resizing=新建Expando();
Layout.created():super.created();
void add_resizeable_属性(HtmlElement e,bool可重设大小){
_冻结调整大小[e]=!可重新设置大小;
}
已冻结(HtmlElement e,
{bool search_down:没错,
布尔搜索:对
}) {
///默认情况下允许调整大小
布尔五世;
如果(向上搜索){
布局t=_获取最顶层的布局();
返回t.isfreezed(
e、 向下搜索:是的,
搜索:错误);
}else if(向下搜索){
v=_冻结_调整大小[e];
v=v==null?false:v;
如果(v)返回true;
返回已冻结的子项(e);
}
返回_冻结_调整大小[e];
}
波尔·伊斯·伊苏儿童(e){
for(儿童中的变量c){
如果(c是!布局)继续;
如果(c)是冻结的(
E
搜索:错误,
向下搜索:正确
))返回true;
}
返回false;
}
布局_获取最顶层的布局(){
布局tm;
var e=此;
而(e是布局){
tm=e;
e=e.父母;
}
返回tm;
}
void(元素[bool search\u up=true]){
///从非所有者中删除expando属性
如果(!children.contains(元素)){
_冻结大小调整[元素]=空;
}
无效对子项强制执行子项(){
for(儿童中的变量c){
如果(c是!布局)继续;
c、 _强制_所有者_独占_expando(元素,false);
}
}
如果(向上搜索){
var tm=_get_top_layout();
tm.\u强制执行\u所有者\u独占\u扩展(元素,假);
}否则{
在子项上强制执行子项();
}
}
附加(e){
super.追加(e);
_强制执行所有人专有扩展(元素);
}
}
一般来说,这个问题是可以避免的,Dart仍然比javascript容易。然而,这是我第一次发现Dart令人沮丧。

如何解决这样的问题?

Weakmap-like-structure-with-keys方法 耶,我终于解决了这个问题!!!!

有键方法

import 'package:mistletoe/mistletoe.dart';
void main(){
    var m = new Mistletoe();
    var t = new DateTime.now();
    m.add( t, 'hi', 'bye');
    print(m.keys(t));//prints 'hi'
    print(m.value(t,'hi'));//prints bye; 
    t = null;
    //With t garbage collected, m is empty now
}
支持伪动态添加属性

import 'package:mistletoe/mistletoe.dart';
Dynamism d = new Dynamism(expert:true);
void main(){
    var o = new Object();
    d.on(o).set('greetings',()=>print('hello world'));
    d.on(o).invoke('greetings');//prints hello world
    o = null;
    //With o garbage collected, d is empty now. 
}
我在这里请求功能:

已发布:

也许您不知道,但Dart中的Expando(Dart VM和dart2js)实际上在技术上是一个弱映射实现(即使文档中没有提到)。我不认为使用WeakMap是共享动态添加的属性的好解决方案。这是关于Expando nature的唯一有用信息。谢谢你信赖那篇写得很糟糕的帖子(太令人震惊了)。正如您所指出的,expando是一个弱映射(尽管在浏览器中,唯一的键是弱的,并且该值在我听说的GC中仍然存在,也许我错了),并且它不是共享的最佳方式。我用它来阻止地图使物体保持活动状态。但是,你给了我一个想法,我可以在我的自定义布局上调用remove或replace时简单地删除键和值。。。仔细想想,我可以用对象的散列作为一个键,所以整件事都很愚蠢。我会试试的tomorrow@DanglingFeet,谢谢你的评论,我现在有点不舒服,也没有信心,但是weakmap似乎没有获取密钥的密钥方法,所以扩展不是一个解决方案。至于你发布的github链接,那里的人们只是对weakref和weakmap之间的区别感到困惑。我想我看到的是dart罕见的弱点,解决方案是使用标准映射和哈希代码组合、树遍历或只是简单地避免设计。@Günter Zöchbauer我在代码中发布了一个功能请求
import 'package:mistletoe/mistletoe.dart';
void main(){
    var m = new Mistletoe();
    var t = new DateTime.now();
    m.add( t, 'hi', 'bye');
    print(m.keys(t));//prints 'hi'
    print(m.value(t,'hi'));//prints bye; 
    t = null;
    //With t garbage collected, m is empty now
}
import 'package:mistletoe/mistletoe.dart';
Dynamism d = new Dynamism(expert:true);
void main(){
    var o = new Object();
    d.on(o).set('greetings',()=>print('hello world'));
    d.on(o).invoke('greetings');//prints hello world
    o = null;
    //With o garbage collected, d is empty now. 
}