Converting a Symbol into a String

2019-06-14 23:19发布

问题:

Is there a way to covert a Symbol into a String?

For instance, a VariableMirror returns Symbols instead of Strings. Is there a way to convert a Symbol into a String, so I can print all the variable names of a class?

回答1:

Use MirrorSystem.getName():

import 'dart:mirrors';

void main() {
  var sym = new Symbol('test');
  print(MirrorSystem.getName(sym));
}

This outputs:

test


回答2:

I'm stack on this question as well.
I can't use 'dart:mirrors' in my package, so using the below:

String s = new Symbol('hi').toString();
s = s.substring(8,pn.length-2);

Looks terrible but it gets the job sort of done. Maybe there is a performance issue though.

Edit:

`Chance is great things breaks in minified JS. Stongly discouraged!` by Günter Zöchbauer

Did not think about this, thanks.
Even if it worked now, there are chances of breakage in the future, so I guess 'toString()' better be avoided.

Confirmed:

Warning: 'hi=' is used reflectively but not in MirrorsUsed. This will break minified code.index.bootstrap.initialize.dart.js:7612 
Warning: 'hi' is used reflectively but not in MirrorsUsed. This will break minified code`


回答3:

It turns out there is an easy solution

print(MirrorSystem.getName(symbol));

prints

somename

see also: https://code.google.com/p/dart/issues/detail?id=17471

EDIT

An interesting comment to the issue linked above from @lrn

It is "difficult to use" on purpose. Symbols can be minified by dart2js, and looking up their original name is only done through the mirror system. This allows dart2js to know whether the feature is used at all, and not include a translation table if it isn't necessary. In general, I recommend coding in a way that doesn't need to convert symbols to strings, if at all possible. Treat them as opaque tokens, and only compare them to other tokens.

The smoke package provides a service for this that gets translated to code by its transformer in a way that also works in minified JavaScript. symbolToName() and nameToSymbol().



回答4:

Some example code:

// Listen for App changes so we can do some things.
app.changes.listen((List<ChangeRecord> records) {
  PropertyChangeRecord record = records[0] as PropertyChangeRecord;
  String changedValue = MirrorSystem.getName(record.name);

  if (changedValue == "pageTitle") {
    print("$changedValue changed!");
  }
}


标签: dart