2014-06-17 1 views

답변

5

당신은 noSuchMethod (emulating functions)

@proxy 
class QueryMap { 
    Map _data = new Map(); 

    QueryMap(); 

    noSuchMethod(Invocation invocation) { 
    if (invocation.isGetter) { 
     var ret = _data[invocation.memberName.toString()]; 
     if (ret != null) { 
     return ret; 
     } else { 
     super.noSuchMethod(invocation); 
     } 
    } 
    if (invocation.isSetter) { 
     _data[invocation.memberName.toString().replaceAll('=', '')] = 
      invocation.positionalArguments.first; 
    } else { 
     super.noSuchMethod(invocation); 
    } 
    } 
} 
void main() { 
    QueryMap qaueryMap = new QueryMap(); 
    qaueryMap.greet = "Hello Dart!"; 
    print(qaueryMap.greet); //Hello Dart! 
} 

을 대체 할 수 있습니다 : 여기

class QueryMap { 
    Map _data; 

    QueryMap(Map this._data); 

    dynamic get(String key, [var defaultValue]) { 
    if(this._data.containsKey(key)) { 
     return this._data[key]; 
    } else if(defaultValue) { 
     return defaultValue; 
    } else { 
     return null; 
    } 
    } 
} 

가 어떻게 작동하는지에 djangos 페이지입니다 : 여기에 지금까지 무엇을 가지고 @PixelElephant 외부지도로 지도 키로 실제 메소드 이름을 사용해야합니다 :

import 'dart:mirrors'; 
@proxy 
class QueryMap { 
    Map _data; 

    QueryMap(this._data); 

    noSuchMethod(Invocation invocation) { 
    if (invocation.isGetter) { 
     var ret = _data[MirrorSystem.getName(invocation.memberName)]; 
     if (ret != null) { 
     return ret; 
     } else { 
     super.noSuchMethod(invocation); 
     } 
    } 
    if (invocation.isSetter) { 
     _data[MirrorSystem.getName(invocation.memberName).replaceAll('=', '')] = 
      invocation.positionalArguments.first; 
    } else { 
     super.noSuchMethod(invocation); 
    } 
    } 
} 
void main() { 
    Map myMap = new Map(); 
    myMap["color"] = "red"; 
    QueryMap qaueryMap = new QueryMap(myMap); 
    qaueryMap.greet = "Hello Dart!"; 
    print(qaueryMap.greet); //Hello Dart! 
    print(qaueryMap.color); //red 
} 

거울의 사용을 방지하기 위해, 당신은 패턴이 심볼의 문자열 직렬화에 일치 또는 외부지도 키 변환 갈 수

@proxy 
class QueryMap { 
    Map _data; 

    QueryMap(Map data) { 
    _data = new Map(); 
    data.forEach((k, v) => _data[new Symbol(k).toString()] = v); 
    } 

    noSuchMethod(Invocation invocation) { 
    if (invocation.isGetter) { 
     var ret = _data[invocation.memberName.toString()]; 
     if (ret != null) { 
     return ret; 
     } else { 
     super.noSuchMethod(invocation); 
     } 
    } 
    if (invocation.isSetter) { 
     _data[invocation.memberName.toString().replaceAll('=', '')] = 
      invocation.positionalArguments.first; 
    } else { 
     super.noSuchMethod(invocation); 
    } 
    } 
} 
void main() { 
    Map myMap = new Map(); 
    myMap["color"] = "red"; 
    QueryMap qaueryMap = new QueryMap(myMap); 
    qaueryMap.greet = "Hello Dart!"; 
    print(qaueryMap.greet); //Hello Dart! 
    print(qaueryMap.color); //red 
} 
+0

주'그 memberName'은'Symbol'이고'MirrorSystem.getName'을 호출하여 (toString 대신) 키로 사용할 수있는 문자열을 가져와야합니다. –

+0

@ PixelElephant 성능에 영향을 줄 수 있으므로 모양이나 형식에 관계없이 미러 사용을 피하려고했습니다. – JAre

+1

예, 여기에 필요합니다. 귀하의 코드는 noSuchMethod를 사용하여 설정하고 얻을 수 있기 때문에 작동합니다. 예를 들어 이미 만든지도를 사용한 경우 'Map map = { 'greet': 'Hello Dart'};', greet이 아닌'Symbol ('greet ')'을 얻으려고하기 때문에 코드가 실패합니다. –