2015-03-18 17 views
2

Я хочу создать символ, равный символу частного простейшего MethodMirror. Однако в документации Symbol указано, что аргумент нового Symbol должен быть действительным общедоступным идентификатором. Если я попытаюсь создать редактор dart const Symbol('_privateIdentifier'), он сообщит мне, что оценка этого константного выражения вызовет исключение - хотя программа работает нормально, и я могу использовать ее без каких-либо проблем.Символ с аргументом частного идентификатора

void main(){ 
    //error flagged in dart editor, though runs fine. 
    const s = const Symbol('_s'); 
    print(s); //Symbol("_s"); 
} 

Кажется, что в системе зеркала используются символы.

import 'dart:mirrors'; 
class ClassA{ 
    _privateMethod(){} 
} 

void main(){ 
    var classMirror = reflect(new ClassA()).type; 
    classMirror.declarations.keys.forEach(print); 
    //Symbol("_privateMethod"), Symbol("ClassA") 
} 

ли документация/ошибка маркировка в редакторе дротика унаследованной ошибки из-за устаревший анализатор дротика? Или планы по обеспечению соблюдения этого общественного требования в будущем? Есть ли другой способ создания уникального идентификационного символа, который будет уменьшен до того же символа, что и простое имя объявления?

ответ

3

Если он не бросает, то VM имеет ошибку в конструкторе const Symbol.

Проблема в том, что «_s» не идентифицирует приватную переменную, не говоря также о том, к какой библиотеке она принадлежит. По этой причине конструктор символов имеет второй аргумент, принимающий LibraryMirror, и передача частному имени без прохождения в зеркало должна бросаться. Это трудно сделать в конструкторе const без необходимости выполнять требования конструктора const (без исполняемого кода!), Что, скорее всего, почему VM не справляется с этим. Он должен быть специально обложен на уровне компилятора.

Вы также обнаружите, что const Symbol('_s') - это не то же самое, что и #_s. Последний создает частный символ для текущей библиотеки, первый (если он работает) создает неличный символ с именем «_s», что не очень полезно. Например, print(identical(#_s, const Symbol('_s'))); печатает false.

+0

Возможно ли иметь символьный литерал, который идентичен методу установки верхнего уровня? Из того, что я понимаю, символы setter всегда заканчиваются на «=», но он выглядит как # x = получает токенизацию в [#x, =]. – DomJack

+0

Установщик 'Symbol' не может быть создан с использованием символьного литерала, но его можно создать с помощью' const Symbol ("x =") '. Это проблема http://dartbug.com/13640. Это несколько затрудняет создание частного символа сеттера, и, если он не обязательно должен быть константой, самый простой способ, вероятно, создать объект с 'noSuchMethod', который пропустит символ' Invocation.memberName'. – lrn

1

Чтобы завладеть символом, я думаю, вам нужно будет получить его от объекта. например

reflect(thing).type.declarations.keys.firstWhere(
    (x) => MirrorSystem.getName(x) == "_privateThingIWant");