简体   繁体   English

Dart中是否有编译器预处理器?

[英]Is there a compiler preprocessor in Dart?

Since a compilation is required before launching a dart application, i wonder if compiler preprocessor is available, or is scheduled in a near future for Dart. 由于在启动dart应用程序之前需要编译,我想知道编译器预处理器是否可用,或者是否在不久的将来为Dart安排。
My searches on the net / inside the dart site have proven unsuccessful so far. 到目前为止,我在网站/飞镖网站内的搜索已被证明是不成功的。

( By preprocessor, i mean something like : (通过预处理器,我的意思是:

#define max(A,B)    ( (A) > (B) ? (A):(B)) 

or : 要么 :

#define NumType double
#define NumTypeZero 0.0

// used with :
NumType myNum = NumTypeZero;

or : 要么 :

#define DEBUG 

// use
#ifdef DEBUG
   print('var1 : $var1, var2:$var2, ...');
#endif

)

Edit : I wonder why there's not allready a pre-processor because it seems we are 'near' from that point : 编辑:我想知道为什么还没有预处理器,因为从那时起我们似乎“接近”:
- Dart has to scan the files for library dependencies to load the libraries in the right order. - Dart必须扫描文件以查找库依赖项,以便按正确的顺序加载库。
- Dart editor also scan files for syntax, type checking and other checks. - Dart编辑器还扫描文件的语法,类型检查和其他检查。
- It's possible to have some automated file processing launched within the editor (i couldn't find a valuable link for this, please let me know if you have one). - 可以在编辑器中启动一些自动文件处理(我找不到有价值的链接,请告诉我,如果你有的话)。

Basically what the other guys said... 基本上其他人说的是......

If you're compiling with dart2js, the tree-shaking will already throw out the code inside an if (DEBUG) {} block, if DEBUG is a constant and false. 如果您正在使用dart2js进行编译,那么如果DEBUG是常量且为false,那么树形抖动就会抛出if(DEBUG){}块内的代码。 So you can just use if statements. 所以你可以使用if语句。

You can also use assert() statements. 您还可以使用assert()语句。 The assert, and the expression passed to it will be thrown away when compiling with dart2js for production mode. 在使用dart2js进行生产模式编译时,断言以及传递给它的表达式将被丢弃。

So this is actually the same behaviour that you'd get with #ifdefs - you can think of dart2js as your preprocessor ;) 所以这实际上与#ifdefs相同 - 您可以将dart2js视为预处理器;)

I also don't see any reason why you would want to use #defines instead of constants. 我也没有看到任何你想要使用#defines而不是常量的原因。

If you want to run your code in the DartVM, you can use dart2js --output-type=dart to do tree-shaking on your dart source. 如果要在DartVM中运行代码,可以使用dart2js --output-type = dart在dart源上进行树形抖动。

Update: Also see String.fromEnvironment() , bool.fromEnvironment() , and int.fromEnvironment() . 更新:另请参阅String.fromEnvironment()bool.fromEnvironment()int.fromEnvironment() You can set these environment variables when compiling by using "dart2js -D<env-var-name>=<value>". 您可以使用“dart2js -D <env-var-name> = <value>”进行编译时设置这些环境变量。

At this time there is no preprocessor for Dart. 目前Dart没有预处理器。 I do not believe that one is planned in the near future either. 我不相信在不久的将来也有计划。 See Issue 7238 问题7238

Dart does not require compilation. Dart不需要编译。 Only to generate Javascript usable by apps outside of the Dart VM. 仅用于生成Dart VM外部应用程序可用的Javascript。 For instance server side Dart scripts never require compilation. 例如,服务器端Dart脚本从不需要编译。 They can generate snapshots to decrease load times but that is less of a compilation step and more storing the state of the VM after the application has launched. 他们可以生成快照以减少加载时间,但这不是编译步骤,而是在应用程序启动后更多地存储VM的状态。

That said, there have been numerous discussions about dependency injection or other dependency management systems based on environment but no consensus or decisions have been reached at this point. 也就是说,已经有很多关于基于环境的依赖注入或其他依赖管理系统的讨论,但目前尚未达成共识或决定。 See Issue 76 问题76

Edit: 编辑:

1) I hesitate to use the term 'right order' on loading libraries. 1)我在加载库时使用“正确的顺序”一词犹豫不决。 For the Dart VM itself, it essentially loads all of the library symbols on loading the script and then begins executing the code and matching the symbols to those in the table. 对于Dart VM本身,它实质上在加载脚本时加载所有库符号,然后开始执行代码并将符号与表中的符号相匹配。 The dart2js compiler does something similar but will then also implement treeshaking to try to isolate code that is not used and omit it from the final compilation. dart2js编译器执行类似的操作,但之后还会实现树形扫描以尝试隔离未使用的代码并从最终编译中省略它。 But I'm far from a VM or JavaScript compiler guru to have more information on how that process is completed. 但是,我远离VM或JavaScript编译器专家,无法获得有关该过程如何完成的更多信息。

2) Similar to other interpreted languages many/most checks are preformed at runtime as opposed to a compile time step. 2)与其他解释语言类似,许多/大多数检查在运行时执行而不是编译时步骤。 And in fact the Dart VM is designed to run with type checking disabled. 事实上,Dart VM设计为在禁用类型检查的情况下运行。 It is only enabled for development and actually imposes a significant penalty on the speed of execution. 它仅用于开发,并且实际上对执行速度施加了重大惩罚。

3) I believe you are referring to the build.dart file. 3)我相信你指的是build.dart文件。 You can find more information at Build.dart and the Dart Editor 您可以在Build.dart和Dart编辑器中找到更多信息

Also note that the Dart editor is actually running a dart script called dart_analyzer to validate the code as you type. 另请注意,Dart编辑器实际上正在运行一个名为dart_analyzer的dart脚本,以便在您键入时验证代码。 It is improving but still far from perfect. 它正在改善,但仍然远非完美。 It does a number of steps to try and assume and associate types and values to the code, but it must also conform to the dart language specification. 它尝试并假设并将类型和值与代码相关联,但它还必须符合dart语言规范。 Thus even if the analyzer is able to assume a type based on surrounding code, it must still provide a warning for instance that type Node has no getter 'value' associated with it, even though the analyzer knows that Node being passed is actually a text input field. 因此,即使分析器能够假设基于周围代码的类型,它仍然必须提供警告,例如类型Node没有与之关联的getter'value',即使分析器知道传递的Node实际上是文本输入字段。

From http://blog.sethladd.com/2013/12/compile-time-dead-code-elimination-with.html 来自http://blog.sethladd.com/2013/12/compile-time-dead-code-elimination-with.html

Suppose you have code like this: 假设你有这样的代码:

log(String msg) {
  if (const String.fromEnvironment('DEBUG') != null) {
    print('debug: $msg');
  }
}

main() {
  log('In production, I do not exist');
}

When compiled with dart2js -DDEBUG=true app.dart , the output includes the logging behavior: 使用dart2js -DDEBUG=true app.dart编译时,输出包括日志记录行为:

  main: function() {
    H.printString("debug: In the production release, I do not exist");
  }

(the log function is inlined, but the print still happens) (日志功能是内联的,但打印仍然发生)

However, if -DDEBUG is not set, the logging behavior is not included in the generated JavaScript code: 但是,如果未设置-DDEBUG,则生成的JavaScript代码中不包含日志记录行为:

  main: function() {
  }

No, there isn't, and I doubt there will be. 不,没有,我怀疑会有。

For your first example, the equivalent would just be to define max(a, b) => a > b ? 对于你的第一个例子,等价只是定义max(a,b)=> a> b? a: b; a:b;

Or, more simply import "dart:math"; 或者,更简单地导入“dart:math”;

which includes that already. 其中包括已经。

The equivalent of the second would be a typedef for NumType, but right now Dart typedefs only work for function types. 第二个的等价物是NumType的typedef,但是现在Dart typedef仅适用于函数类型。 More general typedefs seem likely to show up in later versions. 更常见的typedef似乎可能会出现在更高版本中。 For the 0.0 part, just const numTypeZero = 0.0; 对于0.0部分,只是const numTypeZero = 0.0;

There is no equivalent to ifdef for conditional code execution right now. 现在没有等价于ifdef的条件代码执行。 However, if at the beginning of your program you defined const DEBUG = false; 但是,如果在程序的开头,则定义了const DEBUG = false; and wrote if (DEBUG) print("stuff"); 并写了if(DEBUG)print(“stuff”);

that would accomplish roughly what you want. 这将大致完成你想要的。

The things you're looking for are very much C idioms, and often intended for performance. 你正在寻找的东西是非常多的C语言,通常用于表演。 Dart's compiler is quite clever, and does not need some of these. Dart的编译器非常聪明,不需要其中的一些。

So, for example, defining max that way is presumably to force it to be inlined. 因此,例如,定义最大化方式可能是为了强制它内联。 Dart will inline it all by itself if it thinks it's worthwhile, and has the ability to change its mind part-way through execution. 如果Dart认为这是值得的话,Dart会自行将它全部内联,并且能够通过执行来改变它的思维。 Declaring something as "const" makes it a compile-time constant, so is pretty much the same effect as a #define. 将某些内容声明为“const”会使其成为编译时常量,因此与#define的效果几乎相同。 The ability to reduce the code size by defining symbols like DEBUG is something Dart is missing right now, although conditional compilation is probably more important for other reasons than size. 通过定义像DEBUG这样的符号来减小代码大小的能力是Dart现在所缺少的,尽管条件编译可能比大小更重要。 If you're running in a browser, and the compiler is in the browser, then the point of reduced code size is in the download. 如果您在浏览器中运行,并且编译器在浏览器中,则下载代码大小减少了。 If you wait until the compiler runs, it's too late, you've already downloaded the code. 如果你等到编译器运行,那就太晚了,你已经下载了代码。 If you compile to JS ahead of time, it would omit the code in the if statement qualified by a constant false. 如果提前编译为JS,则会省略if语句中由常量false限定的代码。 There's also a dart2dart mode which would do those sorts of transformations, as well as minification on Dart source. 还有一个dart2dart模式可以进行各种转换,以及Dart源的缩小。 But that's less important until there are browsers that are running Dart natively. 但是,在有本机运行Dart的浏览器之前,这一点就不那么重要了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM