нужна функция Dart mirror instantiate ()

чтобы добавить здравомыслия в свою жизнь, ищу instantiate() функцию как синтаксический сахар для mirror библиотеки Дарта: instantiate( class|type|instance, argArray )

class Klass {
  int i1;
  Klass( int i1 ) {
    this.i1 = (i1 is int) ? i1 : 0;
  }
}
type ktype = Klass;
Klass kinstance = new Klass( 5 );

Klass test1 = instantiate( Klass, [5] );
Klass test2 = instantiate( ktype, [5] );
Klass test3 = instantiate( kinstance, [5] );

в настоящее время 90% моего взаимодействия с mirrors будет покрыто этой функцией. на данный момент слепо вырезание и копирование по чистой глупости. конечно, кто-то умнее меня уже сделал это!


вот instantiate( type, [constructor, positional, named] ) на все случаи жизни:

  • аргументы конструктора, позиционные и именованные являются необязательными
  • тип может быть Type, в экземпляре типа или строковым представлением типа
  • конструктор: например, new Map.from (...) - 'from' является конструктором, либо 'from' или #from
  • positional: позиционные аргументы в списке
  • named: имена аргументов в карте, ключи могут быть 'key' или #key
dynamic instantiate( dynamic v_type, [dynamic v_constructorName, List v_positional, Map v_named] ) {
  Type type =
    ( _type is Type ) ? v_type
    : (v_type is String ) ? str2Type( v_type )
    : reflect(v_type).type.reflectedType;
  Map v_named2 =
    (v_named is Map) ? v_named
    : (v_positional is Map) ? v_positional
    : (v_constructorName is Map) ? v_constructorName
    : {};
  Map named = {};
  v_named2.keys.forEach( (k) => named[(k is Symbol)?k:new Symbol(k)] = v_named2[k] );
  List positional =
    (v_positional is List) ? v_positional
    : (v_constructorName is List) ? v_constructorName : [];
  Symbol constructorName =
    (v_constructorName is Symbol) ? v_constructorName
    : (v_constructorName is String) ? Symbol(v_constructorName)
    : const Symbol('');
  return reflectClass(type).newInstance(constructorName, positional, named).reflectee;
}

person cc young    schedule 20.01.2014    source источник


Ответы (1)


import 'dart:mirrors';

void main() {
  Type ktype = Klass;
  Klass kinstance = new Klass( 5 );
  // Constructor name
  var ctor = const Symbol("");

  Klass test1 = instantiate(Klass, ctor, [1]);
  Klass test2 = instantiate(ktype, ctor, [2]);
  Klass test3 = instantiate(reflect(kinstance).type.reflectedType, ctor, [3]);
  Klass test4 = instantiate(Klass, #fromString, ["4"]);

  print(test1.i1);
  print(test2.i1);
  print(test3.i1);
  print(test4.i1);
}

dynamic instantiate(Type type, Symbol constructorName, List positional, [Map named]) {
  return reflectClass(type).newInstance(constructorName, positional, named).reflectee;
}

class Klass {
  int i1;
  Klass( int i1 ) {
    this.i1 = (i1 is int) ? i1 : 0;
  }

  Klass.fromString(String i) {
    i1 = int.parse(i, onError : (s) => i1 = 0);
  }
}

Выход:

1
2
3
4
person mezoni    schedule 20.01.2014
comment
есть ли причина, по которой вы объявили ctor глобально, а не внутри функции instantiate()? - person cc young; 20.01.2014
comment
@ccyoung есть ли причина, по которой вы объявили ctor глобально, а не в функции instantiate () ?. Пожалуйста, посмотрите обновленный ответ. - person mezoni; 20.01.2014